home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / js / src / jscntxt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  5.1 KB  |  202 lines

  1. /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. /*
  20.  * JS execution context.
  21.  */
  22. #include <stdarg.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include "prtypes.h"
  26. #ifndef NSPR20
  27. #include "prarena.h"
  28. #else
  29. #include "plarena.h"
  30. #endif
  31. #include "prlog.h"
  32. #include "prclist.h"
  33. #include "prprf.h"
  34. #include "jsatom.h"
  35. #include "jscntxt.h"
  36. #include "jsconfig.h"
  37. #include "jsdbgapi.h"
  38. #include "jsgc.h"
  39. #include "jslock.h"
  40. #include "jsobj.h"
  41. #include "jsopcode.h"
  42. #include "jsscan.h"
  43. #include "jsscript.h"
  44.  
  45. JSInterpreterHooks *js_InterpreterHooks = 0;
  46.  
  47. JS_FRIEND_API(void)
  48. js_SetInterpreterHooks(JSInterpreterHooks *hooks)
  49. {
  50.     js_InterpreterHooks = hooks;
  51. }
  52.  
  53. JSContext *
  54. js_NewContext(JSRuntime *rt, size_t stacksize)
  55. {
  56.     JSContext *cx;
  57.  
  58.     cx = malloc(sizeof *cx);
  59.     if (!cx)
  60.     return NULL;
  61.     memset(cx, 0, sizeof *cx);
  62.  
  63.     cx->runtime = rt;
  64.     if (rt->contextList.next == (PRCList *)&rt->contextList) {
  65.     /* First context on this runtime: initialize atoms and keywords. */
  66.     if (!js_InitAtomState(cx, &rt->atomState) ||
  67.         !js_InitScanner(cx)) {
  68.         free(cx);
  69.         return NULL;
  70.     }
  71.     }
  72.  
  73.     PR_APPEND_LINK(&cx->links, &rt->contextList);
  74.     cx->version = JSVERSION_DEFAULT;
  75.     cx->jsop_eq = JSOP_EQ;
  76.     cx->jsop_ne = JSOP_NE;
  77.     PR_InitArenaPool(&cx->stackPool, "stack", stacksize, sizeof(jsval));
  78.     PR_InitArenaPool(&cx->codePool, "code", 1024, sizeof(jsbytecode));
  79.     PR_InitArenaPool(&cx->tempPool, "temp", 1024, sizeof(jsdouble));
  80.  
  81. #if JS_HAS_REGEXPS
  82.     if (!js_InitRegExpStatics(cx, &cx->regExpStatics)) {
  83.     js_DestroyContext(cx);
  84.     return 0;
  85.     }
  86. #endif
  87.     return cx;
  88. }
  89.  
  90. void
  91. js_DestroyContext(JSContext *cx)
  92. {
  93.     JSRuntime *rt;
  94.     JSBool rtempty;
  95.  
  96.     rt = cx->runtime;
  97.     PR_ASSERT(JS_IS_RUNTIME_LOCKED(rt));
  98.  
  99.     /* Remove cx from context list first. */
  100.     PR_REMOVE_LINK(&cx->links);
  101.     rtempty = (rt->contextList.next == (PRCList *)&rt->contextList);
  102.  
  103.     if (js_InterpreterHooks && js_InterpreterHooks->destroyContext) {
  104.     /* This is a stub, but in case it removes roots, call it now. */
  105.         js_InterpreterHooks->destroyContext(cx);
  106.     }
  107.  
  108.     if (rtempty) {
  109.     /* No more contexts: clear debugging state to remove GC roots. */
  110.     JS_ClearAllTraps(cx);
  111.     JS_ClearAllWatchPoints(cx);
  112.     }
  113.  
  114.     /* Remove more GC roots in regExpStatics, then collect garbage. */
  115. #if JS_HAS_REGEXPS
  116.     js_FreeRegExpStatics(cx, &cx->regExpStatics);
  117. #endif
  118.     js_ForceGC(cx);
  119.  
  120.     if (rtempty) {
  121.     /* Free atom state now that we've run the GC. */
  122.     js_FreeAtomState(cx, &rt->atomState);
  123.     }
  124.  
  125.     /* Free the stuff hanging off of cx. */
  126.     PR_FinishArenaPool(&cx->stackPool);
  127.     PR_FinishArenaPool(&cx->codePool);
  128.     PR_FinishArenaPool(&cx->tempPool);
  129.     if (cx->lastMessage)
  130.     free(cx->lastMessage);
  131.     free(cx);
  132. }
  133.  
  134. JSContext *
  135. js_ContextIterator(JSRuntime *rt, JSContext **iterp)
  136. {
  137.     JSContext *cx = *iterp;
  138.  
  139.     PR_ASSERT(JS_IS_RUNTIME_LOCKED(rt));
  140.     if (!cx)
  141.     cx = (JSContext *)rt->contextList.next;
  142.     if ((void *)cx == &rt->contextList)
  143.     return NULL;
  144.     *iterp = (JSContext *)cx->links.next;
  145.     return cx;
  146. }
  147.  
  148. void
  149. js_ReportErrorVA(JSContext *cx, const char *format, va_list ap)
  150. {
  151.     JSStackFrame *fp;
  152.     JSErrorReport report, *reportp;
  153.     char *last;
  154.  
  155.     fp = cx->fp;
  156.     if (fp && fp->script && fp->pc) {
  157.     report.filename = fp->script->filename;
  158.     report.lineno = js_PCToLineNumber(fp->script, fp->pc);
  159.     /* XXX should fetch line somehow */
  160.     report.linebuf = NULL;
  161.     report.tokenptr = NULL;
  162.     reportp = &report;
  163.     } else {
  164.     reportp = NULL;
  165.     }
  166.     last = PR_vsmprintf(format, ap);
  167.     if (!last)
  168.     return;
  169.  
  170.     js_ReportErrorAgain(cx, last, reportp);
  171.     free(last);
  172. }
  173.  
  174. JS_FRIEND_API(void)
  175. js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *reportp)
  176. {
  177.     JSErrorReporter onError;
  178.  
  179.     if (!message)
  180.     return;
  181.     if (cx->lastMessage)
  182.     free(cx->lastMessage);
  183.     cx->lastMessage = JS_strdup(cx, message);
  184.     if (!cx->lastMessage)
  185.     return;
  186.     onError = cx->errorReporter;
  187.     if (onError)
  188.     (*onError)(cx, cx->lastMessage, reportp);
  189. }
  190.  
  191. void
  192. js_ReportIsNotDefined(JSContext *cx, const char *name)
  193. {
  194.     JS_ReportError(cx, "%s is not defined", name);
  195. }
  196.  
  197. #if defined DEBUG && defined XP_UNIX
  198. /* For gdb usage. */
  199. void js_traceon(JSContext *cx)  { cx->tracefp = stderr; }
  200. void js_traceoff(JSContext *cx) { cx->tracefp = NULL; }
  201. #endif
  202.