bug 124474, "add native frame support to jsd"

sr=shaver, r=jband
add JSD_IsStackFrameNative, IsStackFrameDebugger, and IsStackFrameConstructing
add similar attributes to jsdIStackFrame
tweak return values in jsds_FilterHook
don't include dummy stack frames in threadstates

bug 110387, "Crash on exiting venkman"
check to see if the debugger was turned off before going through with an unPause.
This commit is contained in:
rginda%netscape.com 2002-02-14 07:57:30 +00:00
Родитель 6564fd58e3
Коммит 605e3a0d2e
7 изменённых файлов: 331 добавлений и 40 удалений

Просмотреть файл

@ -118,6 +118,16 @@ interface jsdIDebuggerService : nsISupports
*/ */
attribute jsdICallHook functionHook; attribute jsdICallHook functionHook;
/**
* Link native frames in call stacks.
*/
const unsigned long ENABLE_NATIVE_FRAMES = 0x01;
/**
* Debugger service flags.
*/
attribute unsigned long flags;
/** /**
* |true| if the debugger should register an app-start observer in order * |true| if the debugger should register an app-start observer in order
* to begin collecting debug information when mozilla is launched. * to begin collecting debug information when mozilla is launched.
@ -618,6 +628,20 @@ interface jsdIStackFrame : jsdIEphemeral
/** Internal use only. */ /** Internal use only. */
[noscript] readonly attribute JSDStackFrameInfo JSDStackFrameInfo; [noscript] readonly attribute JSDStackFrameInfo JSDStackFrameInfo;
/**
* True if stack frame represents a native frame.
*/
readonly attribute boolean isNative;
/**
* True if stack frame represents a frame created as a result of a debugger
* evaluation.
*/
readonly attribute boolean isDebugger;
/**
* True if stack frame is constructing a new object.
*/
readonly attribute boolean isConstructing;
/** /**
* Link to the caller's stack frame. * Link to the caller's stack frame.
*/ */
@ -627,7 +651,11 @@ interface jsdIStackFrame : jsdIEphemeral
*/ */
readonly attribute jsdIContext executionContext; readonly attribute jsdIContext executionContext;
/** /**
* Script running in this stack frame. * Function name executing in this stack frame.
*/
readonly attribute string functionName;
/**
* Script running in this stack frame, null for native frames.
*/ */
readonly attribute jsdIScript script; readonly attribute jsdIScript script;
/** /**

Просмотреть файл

@ -130,6 +130,7 @@ struct JSDContext
JSCList links; /* we are part of a JSCList */ JSCList links; /* we are part of a JSCList */
JSBool inited; JSBool inited;
void* data; void* data;
uint32 flags;
JSD_ScriptHookProc scriptHook; JSD_ScriptHookProc scriptHook;
void* scriptHookData; void* scriptHookData;
JSD_ExecutionHookProc interruptHook; JSD_ExecutionHookProc interruptHook;
@ -620,11 +621,31 @@ jsd_GetScopeChainForStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate, JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe); JSDStackFrameInfo* jsdframe);
extern JSBool
jsd_IsStackFrameNative(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
extern JSBool
jsd_IsStackFrameDebugger(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
extern JSBool
jsd_IsStackFrameConstructing(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
extern JSDValue* extern JSDValue*
jsd_GetThisForStackFrame(JSDContext* jsdc, jsd_GetThisForStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate, JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe); JSDStackFrameInfo* jsdframe);
extern const char*
jsd_GetNameForStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
extern JSDThreadState* extern JSDThreadState*
jsd_NewThreadState(JSDContext* jsdc, JSContext *cx); jsd_NewThreadState(JSDContext* jsdc, JSContext *cx);

Просмотреть файл

@ -63,13 +63,16 @@ _addNewFrame(JSDContext* jsdc,
JSStackFrame* fp) JSStackFrame* fp)
{ {
JSDStackFrameInfo* jsdframe; JSDStackFrameInfo* jsdframe;
JSDScript* jsdscript; JSDScript* jsdscript = NULL;
JSD_LOCK_SCRIPTS(jsdc); if (!JS_IsNativeFrame(jsdthreadstate->context, fp))
jsdscript = jsd_FindJSDScript(jsdc, script); {
JSD_UNLOCK_SCRIPTS(jsdc); JSD_LOCK_SCRIPTS(jsdc);
if( ! jsdscript ) jsdscript = jsd_FindJSDScript(jsdc, script);
return NULL; JSD_UNLOCK_SCRIPTS(jsdc);
if( ! jsdscript )
return NULL;
}
jsdframe = (JSDStackFrameInfo*) calloc(1, sizeof(JSDStackFrameInfo)); jsdframe = (JSDStackFrameInfo*) calloc(1, sizeof(JSDStackFrameInfo));
if( ! jsdframe ) if( ! jsdframe )
@ -116,10 +119,17 @@ jsd_NewThreadState(JSDContext* jsdc, JSContext *cx )
JSScript* script = JS_GetFrameScript(cx, fp); JSScript* script = JS_GetFrameScript(cx, fp);
jsuword pc = (jsuword) JS_GetFramePC(cx, fp); jsuword pc = (jsuword) JS_GetFramePC(cx, fp);
if( ! script || ! pc || JS_IsNativeFrame(cx, fp) ) /*
continue; * don't construct a JSDStackFrame for dummy frames (those without a
* |this| object, or native frames, if JSD_INCLUDE_NATIVE_FRAMES
_addNewFrame( jsdc, jsdthreadstate, script, pc, fp ); * isn't set.
*/
if (JS_GetFrameThis(cx, fp) &&
((jsdc->flags & JSD_INCLUDE_NATIVE_FRAMES) ||
!JS_IsNativeFrame(cx, fp)))
{
_addNewFrame( jsdc, jsdthreadstate, script, pc, fp );
}
} }
/* if there is no stack, then this threadstate can not be constructed */ /* if there is no stack, then this threadstate can not be constructed */
@ -303,7 +313,6 @@ jsd_GetThisForStackFrame(JSDContext* jsdc,
{ {
JSObject* obj; JSObject* obj;
JSDValue* jsdval = NULL; JSDValue* jsdval = NULL;
JSD_LOCK_THREADSTATES(jsdc); JSD_LOCK_THREADSTATES(jsdc);
if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) ) if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
@ -314,10 +323,82 @@ jsd_GetThisForStackFrame(JSDContext* jsdc,
} }
JSD_UNLOCK_THREADSTATES(jsdc); JSD_UNLOCK_THREADSTATES(jsdc);
return jsdval; return jsdval;
} }
const char*
jsd_GetNameForStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe)
{
const char *rv = NULL;
JSD_LOCK_THREADSTATES(jsdc);
if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
{
JSFunction *fun = JS_GetFrameFunction (jsdthreadstate->context,
jsdframe->fp);
if (fun)
rv = JS_GetFunctionName (fun);
}
JSD_UNLOCK_THREADSTATES(jsdc);
return rv;
}
JSBool
jsd_IsStackFrameNative(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe)
{
JSBool rv;
JSD_LOCK_THREADSTATES(jsdc);
if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
{
rv = JS_IsNativeFrame(jsdthreadstate->context, jsdframe->fp);
}
JSD_UNLOCK_THREADSTATES(jsdc);
return rv;
}
JSBool
jsd_IsStackFrameDebugger(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe)
{
JSBool rv = JS_TRUE;
JSD_LOCK_THREADSTATES(jsdc);
if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
{
rv = JS_IsDebuggerFrame(jsdthreadstate->context, jsdframe->fp);
}
JSD_UNLOCK_THREADSTATES(jsdc);
return rv;
}
JSBool
jsd_IsStackFrameConstructing(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe)
{
JSBool rv = JS_TRUE;
JSD_LOCK_THREADSTATES(jsdc);
if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
{
rv = JS_IsConstructorFrame(jsdthreadstate->context, jsdframe->fp);
}
JSD_UNLOCK_THREADSTATES(jsdc);
return rv;
}
JSBool JSBool
jsd_EvaluateUCScriptInStackFrame(JSDContext* jsdc, jsd_EvaluateUCScriptInStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate, JSDThreadState* jsdthreadstate,

Просмотреть файл

@ -89,7 +89,7 @@ _interpreterTrace(JSDContext* jsdc, JSContext *cx, JSStackFrame *fp,
buf = JS_smprintf("%sentering %s %s this: %0x\n", buf = JS_smprintf("%sentering %s %s this: %0x\n",
_indentSpaces(indent++), _indentSpaces(indent++),
funName, funName,
JS_IsContructorFrame(cx, fp) ? "constructing":"", JS_IsConstructorFrame(cx, fp) ? "constructing":"",
(int)JS_GetFrameThis(cx, fp)); (int)JS_GetFrameThis(cx, fp));
} }
else else
@ -119,7 +119,7 @@ _callHook(JSDContext *jsdc, JSContext *cx, JSStackFrame *fp, JSBool before,
if (!jsdc || !jsdc->inited) if (!jsdc || !jsdc->inited)
return JS_FALSE; return JS_FALSE;
if (before && JS_IsContructorFrame(cx, fp)) if (before && JS_IsConstructorFrame(cx, fp))
jsd_Constructing(jsdc, cx, JS_GetFrameThis(cx, fp), fp); jsd_Constructing(jsdc, cx, JS_GetFrameThis(cx, fp), fp);
if (hook) if (hook)

Просмотреть файл

@ -358,29 +358,24 @@ jsds_FindFilter (jsdIFilter *filter)
PRBool PRBool
jsds_FilterHook (JSDContext *jsdc, JSDThreadState *state) jsds_FilterHook (JSDContext *jsdc, JSDThreadState *state)
{ {
if (!gFilters)
return PR_TRUE;
JSContext *cx = JSD_GetJSContext (jsdc, state); JSContext *cx = JSD_GetJSContext (jsdc, state);
void *glob = NS_STATIC_CAST(void *, JS_GetGlobalObject (cx)); void *glob = NS_STATIC_CAST(void *, JS_GetGlobalObject (cx));
if (!glob) { if (!glob) {
NS_WARNING("No global in threadstate"); NS_WARNING("No global in threadstate");
return PR_TRUE; return PR_FALSE;
} }
JSDStackFrameInfo *frame = JSD_GetStackFrame (jsdc, state); JSDStackFrameInfo *frame = JSD_GetStackFrame (jsdc, state);
if (!frame) { if (!frame) {
NS_WARNING("No frame in threadstate"); NS_WARNING("No frame in threadstate");
return PR_TRUE; return PR_FALSE;
} }
JSDScript *script = JSD_GetScriptForStackFrame (jsdc, state, frame); JSDScript *script = JSD_GetScriptForStackFrame (jsdc, state, frame);
if (!script) { if (!script)
NS_WARNING("No script in threadstate");
return PR_TRUE; return PR_TRUE;
}
jsuint pc = JSD_GetPCForStackFrame (jsdc, state, frame); jsuint pc = JSD_GetPCForStackFrame (jsdc, state, frame);
if (!pc) { if (!pc) {
@ -388,13 +383,16 @@ jsds_FilterHook (JSDContext *jsdc, JSDThreadState *state)
return PR_TRUE; return PR_TRUE;
} }
PRUint32 currentLine = JSD_GetClosestLine (jsdc, script, pc); const char *url = JSD_GetScriptFilename (jsdc, script);
if (!currentLine) { if (!url) {
NS_WARNING("Can't convert pc to line"); NS_WARNING ("Script with no filename");
return PR_TRUE; return PR_FALSE;
} }
const char *url = nsnull; if (!gFilters)
return PR_TRUE;
PRUint32 currentLine = JSD_GetClosestLine (jsdc, script, pc);
PRUint32 len = 0; PRUint32 len = 0;
FilterRecord *currentFilter = gFilters; FilterRecord *currentFilter = gFilters;
do { do {
@ -416,11 +414,8 @@ jsds_FilterHook (JSDContext *jsdc, JSDThreadState *state)
if (currentFilter->patternType == ptIgnore) if (currentFilter->patternType == ptIgnore)
return flags & jsdIFilter::FLAG_PASS; return flags & jsdIFilter::FLAG_PASS;
if (!url) { if (!len)
url = JSD_GetScriptFilename (jsdc, script);
NS_ASSERTION (url, "Script with no filename");
len = PL_strlen(url); len = PL_strlen(url);
}
if (len >= currentFilter->patternLength) { if (len >= currentFilter->patternLength) {
switch (currentFilter->patternType) { switch (currentFilter->patternType) {
@ -1523,6 +1518,48 @@ jsdStackFrame::GetExecutionContext(jsdIContext **_rval)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
jsdStackFrame::GetFunctionName(char **_rval)
{
ASSERT_VALID_EPHEMERAL;
const char *name = JSD_GetNameForStackFrame(mCx, mThreadState,
mStackFrameInfo);
if (!name)
{
/* top level scripts have no function name */
*_rval = nsnull;
return NS_OK;
}
*_rval = ToNewCString(nsDependentCString(name));
if (!*_rval)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
jsdStackFrame::GetIsNative(PRBool *_rval)
{
ASSERT_VALID_EPHEMERAL;
*_rval = JSD_IsStackFrameNative (mCx, mThreadState, mStackFrameInfo);
return NS_OK;
}
NS_IMETHODIMP
jsdStackFrame::GetIsDebugger(PRBool *_rval)
{
ASSERT_VALID_EPHEMERAL;
*_rval = JSD_IsStackFrameDebugger (mCx, mThreadState, mStackFrameInfo);
return NS_OK;
}
NS_IMETHODIMP
jsdStackFrame::GetIsConstructing(PRBool *_rval)
{
ASSERT_VALID_EPHEMERAL;
*_rval = JSD_IsStackFrameConstructing (mCx, mThreadState, mStackFrameInfo);
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
jsdStackFrame::GetScript(jsdIScript **_rval) jsdStackFrame::GetScript(jsdIScript **_rval)
{ {
@ -1539,9 +1576,9 @@ jsdStackFrame::GetPc(PRUint32 *_rval)
ASSERT_VALID_EPHEMERAL; ASSERT_VALID_EPHEMERAL;
JSDScript *script = JSD_GetScriptForStackFrame (mCx, mThreadState, JSDScript *script = JSD_GetScriptForStackFrame (mCx, mThreadState,
mStackFrameInfo); mStackFrameInfo);
jsuword pcbase = JSD_GetClosestPC(mCx, script, 0);
if (!script) if (!script)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
jsuword pcbase = JSD_GetClosestPC(mCx, script, 0);
jsuword pc = JSD_GetPCForStackFrame (mCx, mThreadState, mStackFrameInfo); jsuword pc = JSD_GetPCForStackFrame (mCx, mThreadState, mStackFrameInfo);
*_rval = pc - pcbase; *_rval = pc - pcbase;
@ -1554,8 +1591,14 @@ jsdStackFrame::GetLine(PRUint32 *_rval)
ASSERT_VALID_EPHEMERAL; ASSERT_VALID_EPHEMERAL;
JSDScript *script = JSD_GetScriptForStackFrame (mCx, mThreadState, JSDScript *script = JSD_GetScriptForStackFrame (mCx, mThreadState,
mStackFrameInfo); mStackFrameInfo);
jsuword pc = JSD_GetPCForStackFrame (mCx, mThreadState, mStackFrameInfo); if (script) {
*_rval = JSD_GetClosestLine (mCx, script, pc); jsuword pc = JSD_GetPCForStackFrame (mCx, mThreadState, mStackFrameInfo);
*_rval = JSD_GetClosestLine (mCx, script, pc);
} else {
if (!JSD_IsStackFrameNative(mCx, mThreadState, mStackFrameInfo))
return NS_ERROR_FAILURE;
*_rval = 1;
}
return NS_OK; return NS_OK;
} }
@ -1815,8 +1858,15 @@ NS_IMETHODIMP
jsdValue::GetJsFunctionName(char **_rval) jsdValue::GetJsFunctionName(char **_rval)
{ {
ASSERT_VALID_EPHEMERAL; ASSERT_VALID_EPHEMERAL;
*_rval = const char *name = JSD_GetValueFunctionName(mCx, mValue);
ToNewCString(nsDependentCString(JSD_GetValueFunctionName(mCx, mValue))); if (!name)
{
/* top level scripts have no function name */
*_rval = nsnull;
return NS_OK;
}
*_rval = ToNewCString(nsDependentCString(*_rval));
if (!*_rval) if (!*_rval)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
return NS_OK; return NS_OK;
@ -2082,6 +2132,19 @@ jsdService::SetInitAtStartup (PRBool state)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
jsdService::GetFlags (PRUint32 *_rval)
{
*_rval = JSD_GetContextFlags (mCx);
return NS_OK;
}
NS_IMETHODIMP
jsdService::SetFlags (PRUint32 flags)
{
JSD_SetContextFlags (mCx, flags);
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
jsdService::GetIsOn (PRBool *_rval) jsdService::GetIsOn (PRBool *_rval)
@ -2253,7 +2316,10 @@ jsdService::UnPause(PRUint32 *_rval)
if (mPauseLevel == 0) if (mPauseLevel == 0)
return NS_ERROR_NOT_AVAILABLE; return NS_ERROR_NOT_AVAILABLE;
if (--mPauseLevel == 0) { /* check mOn before we muck with this stuff, it's possible the debugger
* was turned off while we were paused.
*/
if (--mPauseLevel == 0 && mOn) {
if (mErrorHook) if (mErrorHook)
JSD_SetErrorReporter (mCx, jsds_ErrorHookProc, NULL); JSD_SetErrorReporter (mCx, jsds_ErrorHookProc, NULL);
if (mThrowHook) if (mThrowHook)

Просмотреть файл

@ -112,6 +112,20 @@ JSD_GetContextPrivate(JSDContext *jsdc)
return jsd_GetContextPrivate (jsdc); return jsd_GetContextPrivate (jsdc);
} }
JSD_PUBLIC_API(void)
JSD_SetContextFlags(JSDContext *jsdc, uint32 flags)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
jsdc->flags = flags;
}
JSD_PUBLIC_API(uint32)
JSD_GetContextFlags(JSDContext *jsdc)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
return jsdc->flags;
}
JSD_PUBLIC_API(JSDContext*) JSD_PUBLIC_API(JSDContext*)
JSD_JSDContextForJSContext(JSContext* context) JSD_JSDContextForJSContext(JSContext* context)
{ {
@ -623,6 +637,42 @@ JSD_GetThisForStackFrame(JSDContext* jsdc,
return jsd_GetThisForStackFrame(jsdc, jsdthreadstate, jsdframe); return jsd_GetThisForStackFrame(jsdc, jsdthreadstate, jsdframe);
} }
JSD_PUBLIC_API(const char*)
JSD_GetNameForStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
return jsd_GetNameForStackFrame(jsdc, jsdthreadstate, jsdframe);
}
JSD_PUBLIC_API(JSBool)
JSD_IsStackFrameNative(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
return jsd_IsStackFrameNative(jsdc, jsdthreadstate, jsdframe);
}
JSD_PUBLIC_API(JSBool)
JSD_IsStackFrameDebugger(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
return jsd_IsStackFrameDebugger(jsdc, jsdthreadstate, jsdframe);
}
JSD_PUBLIC_API(JSBool)
JSD_IsStackFrameConstructing(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
return jsd_IsStackFrameConstructing(jsdc, jsdthreadstate, jsdframe);
}
JSD_PUBLIC_API(JSBool) JSD_PUBLIC_API(JSBool)
JSD_EvaluateUCScriptInStackFrame(JSDContext* jsdc, JSD_EvaluateUCScriptInStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate, JSDThreadState* jsdthreadstate,

Просмотреть файл

@ -179,6 +179,17 @@ JSD_SetContextPrivate(JSDContext *jsdc, void *data);
extern JSD_PUBLIC_API(void *) extern JSD_PUBLIC_API(void *)
JSD_GetContextPrivate(JSDContext *jsdc); JSD_GetContextPrivate(JSDContext *jsdc);
/*
* Context flags.
*/
#define JSD_INCLUDE_NATIVE_FRAMES 0x1
extern JSD_PUBLIC_API(void)
JSD_SetContextFlags (JSDContext* jsdc, uint32 flags);
extern JSD_PUBLIC_API(uint32)
JSD_GetContextFlags (JSDContext* jsdc);
/* /*
* Notify JSD that this JSContext is 'in use'. This allows JSD to hook the * Notify JSD that this JSContext is 'in use'. This allows JSD to hook the
* ErrorReporter. For the most part this is done automatically whenever * ErrorReporter. For the most part this is done automatically whenever
@ -793,6 +804,40 @@ JSD_GetThisForStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate, JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe); JSDStackFrameInfo* jsdframe);
/*
* Get the name of the function executing in this stack frame. Especially useful
* for native frames (without script objects.)
*/
extern JSD_PUBLIC_API(const char*)
JSD_GetNameForStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
/*
* True if stack frame represents a native frame.
*/
extern JSD_PUBLIC_API(JSBool)
JSD_IsStackFrameNative(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
/*
* True if stack frame represents a frame created as a result of a debugger
* evaluation.
*/
extern JSD_PUBLIC_API(JSBool)
JSD_IsStackFrameDebugger(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
/*
* True if stack frame is constructing a new object.
*/
extern JSD_PUBLIC_API(JSBool)
JSD_IsStackFrameConstructing(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
/* /*
* Evaluate the given unicode source code in the context of the given stack frame. * Evaluate the given unicode source code in the context of the given stack frame.
* returns JS_TRUE and puts result in rval on success, JS_FALSE on failure. * returns JS_TRUE and puts result in rval on success, JS_FALSE on failure.