LCOV - code coverage report
Current view: directory - js/jsd - jsd_stak.c (source / functions) Found Hit Coverage
Test: app.info Lines: 263 119 45.2 %
Date: 2012-06-02 Functions: 26 13 50.0 %

       1                 : /* -*- Mode: C; tab-width: 8; 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 - Call stack support
      40                 :  */
      41                 : 
      42                 : #include "jsd.h"
      43                 : #include "jsfriendapi.h"
      44                 : 
      45                 : #ifdef DEBUG
      46               3 : void JSD_ASSERT_VALID_THREAD_STATE(JSDThreadState* jsdthreadstate)
      47                 : {
      48               3 :     JS_ASSERT(jsdthreadstate);
      49               3 :     JS_ASSERT(jsdthreadstate->stackDepth > 0);
      50               3 : }
      51                 : 
      52               3 : void JSD_ASSERT_VALID_STACK_FRAME(JSDStackFrameInfo* jsdframe)
      53                 : {
      54               3 :     JS_ASSERT(jsdframe);
      55               3 :     JS_ASSERT(jsdframe->jsdthreadstate);
      56               3 : }
      57                 : #endif
      58                 : 
      59                 : static JSDStackFrameInfo* 
      60              21 : _addNewFrame(JSDContext*        jsdc,
      61                 :              JSDThreadState*    jsdthreadstate,
      62                 :              JSScript*          script,
      63                 :              uintptr_t          pc,
      64                 :              JSStackFrame*      fp)
      65                 : {
      66                 :     JSDStackFrameInfo* jsdframe;
      67              21 :     JSDScript*         jsdscript = NULL;
      68                 : 
      69              21 :     if (JS_IsScriptFrame(jsdthreadstate->context, fp))
      70                 :     {
      71              21 :         JSD_LOCK_SCRIPTS(jsdc);
      72              21 :         jsdscript = jsd_FindJSDScript(jsdc, script);
      73              21 :         JSD_UNLOCK_SCRIPTS(jsdc);
      74              21 :         if (!jsdscript || (jsdc->flags & JSD_HIDE_DISABLED_FRAMES &&
      75               0 :                            !JSD_IS_DEBUG_ENABLED(jsdc, jsdscript)))
      76                 :         {
      77               5 :             return NULL;
      78                 :         }
      79                 : 
      80              16 :         if (!JSD_IS_DEBUG_ENABLED(jsdc, jsdscript))
      81               0 :             jsdthreadstate->flags |= TS_HAS_DISABLED_FRAME;
      82                 :     }
      83                 :     
      84              16 :     jsdframe = (JSDStackFrameInfo*) calloc(1, sizeof(JSDStackFrameInfo));
      85              16 :     if( ! jsdframe )
      86               0 :         return NULL;
      87                 : 
      88              16 :     jsdframe->jsdthreadstate = jsdthreadstate;
      89              16 :     jsdframe->jsdscript      = jsdscript;
      90              16 :     jsdframe->pc             = pc;
      91              16 :     jsdframe->fp             = fp;
      92                 : 
      93              16 :     JS_APPEND_LINK(&jsdframe->links, &jsdthreadstate->stack);
      94              16 :     jsdthreadstate->stackDepth++;
      95                 : 
      96              16 :     return jsdframe;
      97                 : }
      98                 : 
      99                 : static void
     100              16 : _destroyFrame(JSDStackFrameInfo* jsdframe)
     101                 : {
     102                 :     /* kill any alloc'd objects in frame here... */
     103                 : 
     104              16 :     if( jsdframe )
     105              16 :         free(jsdframe);
     106              16 : }
     107                 : 
     108                 : JSDThreadState*
     109               5 : jsd_NewThreadState(JSDContext* jsdc, JSContext *cx )
     110                 : {
     111                 :     JSDThreadState* jsdthreadstate;
     112               5 :     JSStackFrame *  iter = NULL;
     113                 :     JSStackFrame *  fp;
     114                 : 
     115               5 :     jsdthreadstate = (JSDThreadState*)calloc(1, sizeof(JSDThreadState));
     116               5 :     if( ! jsdthreadstate )
     117               0 :         return NULL;
     118                 : 
     119               5 :     jsdthreadstate->context = cx;
     120               5 :     jsdthreadstate->thread = JSD_CURRENT_THREAD();
     121               5 :     JS_INIT_CLIST(&jsdthreadstate->stack);
     122               5 :     jsdthreadstate->stackDepth = 0;
     123                 : 
     124               5 :     JS_BeginRequest(jsdthreadstate->context);
     125               5 :     while( NULL != (fp = JS_FrameIterator(cx, &iter)) )
     126                 :     {
     127              21 :         JSScript* script = JS_GetFrameScript(cx, fp);
     128              21 :         uintptr_t  pc = (uintptr_t) JS_GetFramePC(cx, fp);
     129                 :         jsval dummyThis;
     130                 : 
     131                 :         /*
     132                 :          * don't construct a JSDStackFrame for dummy frames (those without a
     133                 :          * |this| object, or native frames, if JSD_INCLUDE_NATIVE_FRAMES
     134                 :          * isn't set.
     135                 :          */
     136              42 :         if (JS_GetFrameThis(cx, fp, &dummyThis) &&
     137              42 :             ((jsdc->flags & JSD_INCLUDE_NATIVE_FRAMES) ||
     138              21 :              JS_IsScriptFrame(cx, fp)))
     139                 :         {
     140                 :             JSDStackFrameInfo *frame;
     141                 : 
     142              21 :             frame = _addNewFrame( jsdc, jsdthreadstate, script, pc, fp );
     143                 : 
     144              42 :             if ((jsdthreadstate->stackDepth == 0 && !frame) ||
     145              31 :                 (jsdthreadstate->stackDepth == 1 && frame &&
     146              10 :                  frame->jsdscript && !JSD_IS_DEBUG_ENABLED(jsdc, frame->jsdscript)))
     147                 :             {
     148                 :                 /*
     149                 :                  * if we failed to create the first frame, or the top frame
     150                 :                  * is not enabled for debugging, fail the entire thread state.
     151                 :                  */
     152               0 :                 JS_INIT_CLIST(&jsdthreadstate->links);
     153               0 :                 JS_EndRequest(jsdthreadstate->context);
     154               0 :                 jsd_DestroyThreadState(jsdc, jsdthreadstate);
     155               0 :                 return NULL;
     156                 :             }
     157                 :         }
     158                 :     }
     159               5 :     JS_EndRequest(jsdthreadstate->context);
     160                 : 
     161               5 :     if (jsdthreadstate->stackDepth == 0)
     162                 :     {
     163               0 :         free(jsdthreadstate);
     164               0 :         return NULL;
     165                 :     }
     166                 :     
     167               5 :     JSD_LOCK_THREADSTATES(jsdc);
     168               5 :     JS_APPEND_LINK(&jsdthreadstate->links, &jsdc->threadsStates);
     169               5 :     JSD_UNLOCK_THREADSTATES(jsdc);
     170                 : 
     171               5 :     return jsdthreadstate;
     172                 : }
     173                 : 
     174                 : void
     175               5 : jsd_DestroyThreadState(JSDContext* jsdc, JSDThreadState* jsdthreadstate)
     176                 : {
     177                 :     JSDStackFrameInfo* jsdframe;
     178                 :     JSCList* list;
     179                 : 
     180               5 :     JS_ASSERT(jsdthreadstate);
     181               5 :     JS_ASSERT(JSD_CURRENT_THREAD() == jsdthreadstate->thread);
     182                 : 
     183               5 :     JSD_LOCK_THREADSTATES(jsdc);
     184               5 :     JS_REMOVE_LINK(&jsdthreadstate->links);
     185               5 :     JSD_UNLOCK_THREADSTATES(jsdc);
     186                 : 
     187               5 :     list = &jsdthreadstate->stack;
     188              26 :     while( (JSDStackFrameInfo*)list != (jsdframe = (JSDStackFrameInfo*)list->next) )
     189                 :     {
     190              16 :         JS_REMOVE_LINK(&jsdframe->links);
     191              16 :         _destroyFrame(jsdframe);
     192                 :     }
     193               5 :     free(jsdthreadstate);
     194               5 : }
     195                 : 
     196                 : unsigned
     197               0 : jsd_GetCountOfStackFrames(JSDContext* jsdc, JSDThreadState* jsdthreadstate)
     198                 : {
     199               0 :     unsigned count = 0;
     200                 : 
     201               0 :     JSD_LOCK_THREADSTATES(jsdc);
     202                 : 
     203               0 :     if( jsd_IsValidThreadState(jsdc, jsdthreadstate) )
     204               0 :         count = jsdthreadstate->stackDepth;
     205                 : 
     206               0 :     JSD_UNLOCK_THREADSTATES(jsdc);
     207                 : 
     208               0 :     return count;
     209                 : }
     210                 : 
     211                 : JSDStackFrameInfo*
     212               2 : jsd_GetStackFrame(JSDContext* jsdc, JSDThreadState* jsdthreadstate)
     213                 : {
     214               2 :     JSDStackFrameInfo* jsdframe = NULL;
     215                 : 
     216               2 :     JSD_LOCK_THREADSTATES(jsdc);
     217                 : 
     218               2 :     if( jsd_IsValidThreadState(jsdc, jsdthreadstate) )
     219               2 :         jsdframe = (JSDStackFrameInfo*) JS_LIST_HEAD(&jsdthreadstate->stack);
     220               2 :     JSD_UNLOCK_THREADSTATES(jsdc);
     221                 : 
     222               2 :     return jsdframe;
     223                 : }
     224                 : 
     225                 : JSContext *
     226               1 : jsd_GetJSContext (JSDContext* jsdc, JSDThreadState* jsdthreadstate)
     227                 : {
     228               1 :     JSContext* cx = NULL;
     229                 : 
     230               1 :     JSD_LOCK_THREADSTATES(jsdc);
     231               1 :     if( jsd_IsValidThreadState(jsdc, jsdthreadstate) )
     232               1 :         cx = jsdthreadstate->context;
     233               1 :     JSD_UNLOCK_THREADSTATES(jsdc);
     234                 : 
     235               1 :     return cx;
     236                 : }
     237                 :     
     238                 : JSDStackFrameInfo*
     239               0 : jsd_GetCallingStackFrame(JSDContext* jsdc, 
     240                 :                          JSDThreadState* jsdthreadstate,
     241                 :                          JSDStackFrameInfo* jsdframe)
     242                 : {
     243               0 :     JSDStackFrameInfo* nextjsdframe = NULL;
     244                 : 
     245               0 :     JSD_LOCK_THREADSTATES(jsdc);
     246                 : 
     247               0 :     if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
     248               0 :         if( JS_LIST_HEAD(&jsdframe->links) != &jsdframe->jsdthreadstate->stack )
     249               0 :             nextjsdframe = (JSDStackFrameInfo*) JS_LIST_HEAD(&jsdframe->links);
     250                 : 
     251               0 :     JSD_UNLOCK_THREADSTATES(jsdc);
     252                 : 
     253               0 :     return nextjsdframe;
     254                 : }
     255                 : 
     256                 : JSDScript*
     257               1 : jsd_GetScriptForStackFrame(JSDContext* jsdc, 
     258                 :                            JSDThreadState* jsdthreadstate,
     259                 :                            JSDStackFrameInfo* jsdframe)
     260                 : {
     261               1 :     JSDScript* jsdscript = NULL;
     262                 : 
     263               1 :     JSD_LOCK_THREADSTATES(jsdc);
     264                 : 
     265               1 :     if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
     266               1 :         jsdscript = jsdframe->jsdscript;
     267                 : 
     268               1 :     JSD_UNLOCK_THREADSTATES(jsdc);
     269                 : 
     270               1 :     return jsdscript;
     271                 : }
     272                 : 
     273                 : uintptr_t
     274               1 : jsd_GetPCForStackFrame(JSDContext* jsdc, 
     275                 :                        JSDThreadState* jsdthreadstate,
     276                 :                        JSDStackFrameInfo* jsdframe)
     277                 : {
     278               1 :     uintptr_t pc = 0;
     279                 : 
     280               1 :     JSD_LOCK_THREADSTATES(jsdc);
     281                 : 
     282               1 :     if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
     283               1 :         pc = jsdframe->pc;
     284                 : 
     285               1 :     JSD_UNLOCK_THREADSTATES(jsdc);
     286                 : 
     287               1 :     return pc;
     288                 : }
     289                 : 
     290                 : JSDValue*
     291               0 : jsd_GetCallObjectForStackFrame(JSDContext* jsdc, 
     292                 :                                JSDThreadState* jsdthreadstate,
     293                 :                                JSDStackFrameInfo* jsdframe)
     294                 : {
     295                 :     JSObject* obj;
     296               0 :     JSDValue* jsdval = NULL;
     297                 : 
     298               0 :     JSD_LOCK_THREADSTATES(jsdc);
     299                 : 
     300               0 :     if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
     301                 :     {
     302               0 :         obj = JS_GetFrameCallObject(jsdthreadstate->context, jsdframe->fp); 
     303               0 :         if(obj)                                                             
     304               0 :             jsdval = JSD_NewValue(jsdc, OBJECT_TO_JSVAL(obj));              
     305                 :     }
     306                 : 
     307               0 :     JSD_UNLOCK_THREADSTATES(jsdc);
     308                 : 
     309               0 :     return jsdval;
     310                 : }
     311                 : 
     312                 : JSDValue*
     313               1 : jsd_GetScopeChainForStackFrame(JSDContext* jsdc, 
     314                 :                                JSDThreadState* jsdthreadstate,
     315                 :                                JSDStackFrameInfo* jsdframe)
     316                 : {
     317                 :     JSObject* obj;
     318               1 :     JSDValue* jsdval = NULL;
     319                 : 
     320               1 :     JSD_LOCK_THREADSTATES(jsdc);
     321                 : 
     322               1 :     if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
     323                 :     {
     324               1 :         JS_BeginRequest(jsdthreadstate->context);
     325               1 :         obj = JS_GetFrameScopeChain(jsdthreadstate->context, jsdframe->fp); 
     326               1 :         JS_EndRequest(jsdthreadstate->context);
     327               1 :         if(obj)                                                             
     328               1 :             jsdval = JSD_NewValue(jsdc, OBJECT_TO_JSVAL(obj));              
     329                 :     }
     330                 : 
     331               1 :     JSD_UNLOCK_THREADSTATES(jsdc);
     332                 : 
     333               1 :     return jsdval;
     334                 : }
     335                 : 
     336                 : JSDValue*
     337               0 : jsd_GetThisForStackFrame(JSDContext* jsdc, 
     338                 :                          JSDThreadState* jsdthreadstate,
     339                 :                          JSDStackFrameInfo* jsdframe)
     340                 : {
     341                 :     JSObject* obj;
     342               0 :     JSDValue* jsdval = NULL;
     343               0 :     JSD_LOCK_THREADSTATES(jsdc);
     344                 : 
     345               0 :     if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
     346                 :     {
     347                 :         JSBool ok;
     348                 :         jsval thisval;
     349               0 :         JS_BeginRequest(jsdthreadstate->context);
     350               0 :         ok = JS_GetFrameThis(jsdthreadstate->context, jsdframe->fp, &thisval);
     351               0 :         JS_EndRequest(jsdthreadstate->context);
     352               0 :         if(ok)
     353               0 :             jsdval = JSD_NewValue(jsdc, thisval);
     354                 :     }
     355                 : 
     356               0 :     JSD_UNLOCK_THREADSTATES(jsdc);
     357               0 :     return jsdval;
     358                 : }
     359                 : 
     360                 : JSString*
     361               0 : jsd_GetIdForStackFrame(JSDContext* jsdc, 
     362                 :                        JSDThreadState* jsdthreadstate,
     363                 :                        JSDStackFrameInfo* jsdframe)
     364                 : {
     365               0 :     JSString *rv = NULL;
     366                 :     
     367               0 :     JSD_LOCK_THREADSTATES(jsdc);
     368                 :     
     369               0 :     if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
     370                 :     {
     371               0 :         JSFunction *fun = JS_GetFrameFunction (jsdthreadstate->context,
     372                 :                                                jsdframe->fp);
     373               0 :         if( fun )
     374                 :         {
     375               0 :             rv = JS_GetFunctionId (fun);
     376                 : 
     377                 :             /*
     378                 :              * For compatibility we return "anonymous", not an empty string
     379                 :              * here.
     380                 :              */
     381               0 :             if( !rv )
     382               0 :                 rv = JS_GetAnonymousString(jsdc->jsrt);
     383                 :         }
     384                 :     }
     385                 :     
     386               0 :     JSD_UNLOCK_THREADSTATES(jsdc);
     387               0 :     return rv;
     388                 : }
     389                 : 
     390                 : JSBool
     391               0 : jsd_IsStackFrameDebugger(JSDContext* jsdc, 
     392                 :                          JSDThreadState* jsdthreadstate,
     393                 :                          JSDStackFrameInfo* jsdframe)
     394                 : {
     395               0 :     JSBool rv = JS_TRUE;
     396               0 :     JSD_LOCK_THREADSTATES(jsdc);
     397                 : 
     398               0 :     if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
     399                 :     {
     400               0 :         rv = JS_IsDebuggerFrame(jsdthreadstate->context, jsdframe->fp);
     401                 :     }
     402                 : 
     403               0 :     JSD_UNLOCK_THREADSTATES(jsdc);
     404               0 :     return rv;
     405                 : }
     406                 : 
     407                 : JSBool
     408               0 : jsd_IsStackFrameConstructing(JSDContext* jsdc, 
     409                 :                              JSDThreadState* jsdthreadstate,
     410                 :                              JSDStackFrameInfo* jsdframe)
     411                 : {
     412               0 :     JSBool rv = JS_TRUE;
     413               0 :     JSD_LOCK_THREADSTATES(jsdc);
     414                 : 
     415               0 :     if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
     416                 :     {
     417               0 :         rv = JS_IsConstructorFrame(jsdthreadstate->context, jsdframe->fp);
     418                 :     }
     419                 : 
     420               0 :     JSD_UNLOCK_THREADSTATES(jsdc);
     421               0 :     return rv;
     422                 : }
     423                 : 
     424                 : JSBool
     425               0 : jsd_EvaluateUCScriptInStackFrame(JSDContext* jsdc, 
     426                 :                                  JSDThreadState* jsdthreadstate,
     427                 :                                  JSDStackFrameInfo* jsdframe,
     428                 :                                  const jschar *bytes, unsigned length,
     429                 :                                  const char *filename, unsigned lineno,
     430                 :                                  JSBool eatExceptions, jsval *rval)
     431                 : {
     432                 :     JSBool retval;
     433                 :     JSBool valid;
     434               0 :     JSExceptionState* exceptionState = NULL;
     435                 :     JSContext* cx;
     436                 : 
     437               0 :     JS_ASSERT(JSD_CURRENT_THREAD() == jsdthreadstate->thread);
     438                 : 
     439               0 :     JSD_LOCK_THREADSTATES(jsdc);
     440               0 :     valid = jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe);
     441               0 :     JSD_UNLOCK_THREADSTATES(jsdc);
     442                 : 
     443               0 :     if( ! valid )
     444               0 :         return JS_FALSE;
     445                 : 
     446               0 :     cx = jsdthreadstate->context;
     447               0 :     JS_ASSERT(cx);
     448                 : 
     449               0 :     if (eatExceptions)
     450               0 :         exceptionState = JS_SaveExceptionState(cx);
     451               0 :     JS_ClearPendingException(cx);
     452               0 :     jsd_StartingEvalUsingFilename(jsdc, filename);
     453               0 :     retval = JS_EvaluateUCInStackFrame(cx, jsdframe->fp, bytes, length, 
     454                 :                                        filename, lineno, rval);
     455               0 :     jsd_FinishedEvalUsingFilename(jsdc, filename);
     456               0 :     if (eatExceptions)
     457               0 :         JS_RestoreExceptionState(cx, exceptionState);
     458                 : 
     459               0 :     return retval;
     460                 : }
     461                 : 
     462                 : JSBool
     463               0 : jsd_EvaluateScriptInStackFrame(JSDContext* jsdc, 
     464                 :                                JSDThreadState* jsdthreadstate,
     465                 :                                JSDStackFrameInfo* jsdframe,
     466                 :                                const char *bytes, unsigned length,
     467                 :                                const char *filename, unsigned lineno,
     468                 :                                JSBool eatExceptions, jsval *rval)
     469                 : {
     470                 :     JSBool retval;
     471                 :     JSBool valid;
     472               0 :     JSExceptionState* exceptionState = NULL;
     473                 :     JSContext *cx;
     474                 : 
     475               0 :     JS_ASSERT(JSD_CURRENT_THREAD() == jsdthreadstate->thread);
     476                 : 
     477               0 :     JSD_LOCK_THREADSTATES(jsdc);
     478               0 :     valid = jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe);
     479               0 :     JSD_UNLOCK_THREADSTATES(jsdc);
     480                 : 
     481               0 :     if (!valid)
     482               0 :         return JS_FALSE;
     483                 : 
     484               0 :     cx = jsdthreadstate->context;
     485               0 :     JS_ASSERT(cx);
     486                 : 
     487               0 :     if (eatExceptions)
     488               0 :         exceptionState = JS_SaveExceptionState(cx);
     489               0 :     JS_ClearPendingException(cx);
     490               0 :     jsd_StartingEvalUsingFilename(jsdc, filename);
     491               0 :     retval = JS_EvaluateInStackFrame(cx, jsdframe->fp, bytes, length,
     492                 :                                      filename, lineno, rval);
     493               0 :     jsd_FinishedEvalUsingFilename(jsdc, filename);
     494               0 :     if (eatExceptions)
     495               0 :         JS_RestoreExceptionState(cx, exceptionState);
     496                 : 
     497               0 :     return retval;
     498                 : }
     499                 : 
     500                 : JSString*
     501               0 : jsd_ValToStringInStackFrame(JSDContext* jsdc, 
     502                 :                             JSDThreadState* jsdthreadstate,
     503                 :                             JSDStackFrameInfo* jsdframe,
     504                 :                             jsval val)
     505                 : {
     506                 :     JSBool valid;
     507                 :     JSString* retval;
     508                 :     JSExceptionState* exceptionState;
     509                 :     JSContext* cx;
     510                 : 
     511               0 :     JSD_LOCK_THREADSTATES(jsdc);
     512               0 :     valid = jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe);
     513               0 :     JSD_UNLOCK_THREADSTATES(jsdc);
     514                 : 
     515               0 :     if( ! valid )
     516               0 :         return NULL;
     517                 : 
     518               0 :     cx = jsdthreadstate->context;
     519               0 :     JS_ASSERT(cx);
     520                 : 
     521               0 :     exceptionState = JS_SaveExceptionState(cx);
     522               0 :     retval = JS_ValueToString(cx, val);
     523               0 :     JS_RestoreExceptionState(cx, exceptionState);
     524                 : 
     525               0 :     return retval;
     526                 : }
     527                 : 
     528                 : JSBool
     529               6 : jsd_IsValidThreadState(JSDContext*        jsdc, 
     530                 :                        JSDThreadState*    jsdthreadstate)
     531                 : {
     532                 :     JSDThreadState *cur;
     533                 : 
     534               6 :     JS_ASSERT( JSD_THREADSTATES_LOCKED(jsdc) );
     535                 : 
     536              12 :     for( cur = (JSDThreadState*)jsdc->threadsStates.next;
     537               6 :          cur != (JSDThreadState*)&jsdc->threadsStates;
     538               0 :          cur = (JSDThreadState*)cur->links.next ) 
     539                 :     {
     540               6 :         if( cur == jsdthreadstate )
     541               6 :             return JS_TRUE;
     542                 :     }
     543               0 :     return JS_FALSE;
     544                 : }    
     545                 : 
     546                 : JSBool
     547               3 : jsd_IsValidFrameInThreadState(JSDContext*        jsdc, 
     548                 :                               JSDThreadState*    jsdthreadstate,
     549                 :                               JSDStackFrameInfo* jsdframe)
     550                 : {
     551               3 :     JS_ASSERT(JSD_THREADSTATES_LOCKED(jsdc));
     552                 : 
     553               3 :     if( ! jsd_IsValidThreadState(jsdc, jsdthreadstate) )
     554               0 :         return JS_FALSE;
     555               3 :     if( jsdframe->jsdthreadstate != jsdthreadstate )
     556               0 :         return JS_FALSE;
     557                 : 
     558               3 :     JSD_ASSERT_VALID_THREAD_STATE(jsdthreadstate);
     559               3 :     JSD_ASSERT_VALID_STACK_FRAME(jsdframe);
     560                 :     
     561               3 :     return JS_TRUE;
     562                 : }
     563                 : 
     564                 : static JSContext*
     565               0 : _getContextForThreadState(JSDContext* jsdc, JSDThreadState* jsdthreadstate)
     566                 : {
     567                 :     JSBool valid;
     568               0 :     JSD_LOCK_THREADSTATES(jsdc);
     569               0 :     valid = jsd_IsValidThreadState(jsdc, jsdthreadstate);
     570               0 :     JSD_UNLOCK_THREADSTATES(jsdc);
     571               0 :     if( valid )
     572               0 :         return jsdthreadstate->context;
     573               0 :     return NULL;
     574                 : }        
     575                 : 
     576                 : JSDValue*
     577               0 : jsd_GetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate)
     578                 : {
     579                 :     JSContext* cx;
     580                 :     jsval val;
     581                 : 
     582               0 :     if(!(cx = _getContextForThreadState(jsdc, jsdthreadstate)))
     583               0 :         return NULL;
     584                 : 
     585               0 :     if(JS_GetPendingException(cx, &val))
     586               0 :         return jsd_NewValue(jsdc, val);
     587               0 :     return NULL;
     588                 : }        
     589                 : 
     590                 : JSBool
     591               0 : jsd_SetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate, 
     592                 :                  JSDValue* jsdval)
     593                 : {
     594                 :     JSContext* cx;
     595                 : 
     596               0 :     if(!(cx = _getContextForThreadState(jsdc, jsdthreadstate)))
     597               0 :         return JS_FALSE;
     598                 : 
     599               0 :     if(jsdval)
     600               0 :         JS_SetPendingException(cx, JSD_GetValueWrappedJSVal(jsdc, jsdval));
     601                 :     else
     602               0 :         JS_ClearPendingException(cx);
     603               0 :     return JS_TRUE;
     604                 : }
     605                 : 

Generated by: LCOV version 1.7