⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jscntxt.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** *//* * JS execution context. */#include "jsstddef.h"#include <stdarg.h>#include <stdlib.h>#include <string.h>#include "jstypes.h"#include "jsarena.h" /* Added by JSIFY */#include "jsutil.h" /* Added by JSIFY */#include "jsclist.h"#include "jsprf.h"#include "jsatom.h"#include "jscntxt.h"#include "jsconfig.h"#include "jsdbgapi.h"#include "jsexn.h"#include "jsgc.h"#include "jslock.h"#include "jsnum.h"#include "jsobj.h"#include "jsopcode.h"#include "jsscan.h"#include "jsscript.h"#include "jsstr.h"JSContext *js_NewContext(JSRuntime *rt, size_t stackChunkSize){    JSContext *cx;    JSBool ok, first;    cx = (JSContext *) malloc(sizeof *cx);    if (!cx)        return NULL;    memset(cx, 0, sizeof *cx);    cx->runtime = rt;#if JS_STACK_GROWTH_DIRECTION > 0    cx->stackLimit = (jsuword)-1;#endif#ifdef JS_THREADSAFE    js_InitContextForLocking(cx);#endif    JS_LOCK_GC(rt);    for (;;) {        first = (rt->contextList.next == &rt->contextList);        if (rt->state == JSRTS_UP) {            JS_ASSERT(!first);            break;        }        if (rt->state == JSRTS_DOWN) {            JS_ASSERT(first);            rt->state = JSRTS_LAUNCHING;            break;        }        JS_WAIT_CONDVAR(rt->stateChange, JS_NO_TIMEOUT);    }    JS_APPEND_LINK(&cx->links, &rt->contextList);    JS_UNLOCK_GC(rt);    /*     * First we do the infallible, every-time per-context initializations.     * Should a later, fallible initialization (js_InitRegExpStatics, e.g.,     * or the stuff under 'if (first)' below) fail, at least the version     * and arena-pools will be valid and safe to use (say, from the last GC     * done by js_DestroyContext).     */    cx->version = JSVERSION_DEFAULT;    cx->jsop_eq = JSOP_EQ;    cx->jsop_ne = JSOP_NE;    cx->caseSensitive = JS_TRUE;    JS_InitArenaPool(&cx->stackPool, "stack", stackChunkSize, sizeof(jsval));    JS_InitArenaPool(&cx->tempPool, "temp", 1024, sizeof(jsdouble));#if JS_HAS_REGEXPS    if (!js_InitRegExpStatics(cx, &cx->regExpStatics)) {        js_DestroyContext(cx, JS_NO_GC);        return NULL;    }#endif#if JS_HAS_EXCEPTIONS    cx->throwing = JS_FALSE;#endif    /*     * If cx is the first context on this runtime, initialize well-known atoms,     * keywords, numbers, and strings.  If one of these steps should fail, the     * runtime will be left in a partially initialized state, with zeroes and     * nulls stored in the default-initialized remainder of the struct.  We'll     * clean the runtime up under js_DestroyContext, because cx will be "last"     * as well as "first".     */    if (first) {        ok = (rt->atomState.liveAtoms == 0)             ? js_InitAtomState(cx, &rt->atomState)             : js_InitPinnedAtoms(cx, &rt->atomState);        if (ok)            ok = js_InitScanner(cx);        if (ok)            ok = js_InitRuntimeNumberState(cx);        if (ok)            ok = js_InitRuntimeScriptState(cx);        if (ok)            ok = js_InitRuntimeStringState(cx);        if (!ok) {            js_DestroyContext(cx, JS_NO_GC);            return NULL;        }        JS_LOCK_GC(rt);        rt->state = JSRTS_UP;        JS_NOTIFY_ALL_CONDVAR(rt->stateChange);        JS_UNLOCK_GC(rt);    }    return cx;}voidjs_DestroyContext(JSContext *cx, JSGCMode gcmode){    JSRuntime *rt;    JSBool last;    JSArgumentFormatMap *map;    rt = cx->runtime;    /* Remove cx from context list first. */    JS_LOCK_GC(rt);    JS_ASSERT(rt->state == JSRTS_UP || rt->state == JSRTS_LAUNCHING);    JS_REMOVE_LINK(&cx->links);    last = (rt->contextList.next == &rt->contextList);    if (last)        rt->state = JSRTS_LANDING;    JS_UNLOCK_GC(rt);    if (last) {#ifdef JS_THREADSAFE        /*         * If cx is not in a request already, begin one now so that we wait         * for any racing GC started on a not-last context to finish, before         * we plow ahead and unpin atoms.  Note that even though we begin a         * request here if necessary, we end all requests on cx below before         * forcing a final GC.  This lets any not-last context destruction         * racing in another thread try to force or maybe run the GC, but by         * that point, rt->state will not be JSRTS_UP, and that GC attempt         * will return early.         */        if (cx->requestDepth == 0)            JS_BeginRequest(cx);#endif        /* Unpin all pinned atoms before final GC. */        js_UnpinPinnedAtoms(&rt->atomState);        /* Unlock and clear GC things held by runtime pointers. */        js_FinishRuntimeNumberState(cx);        js_FinishRuntimeStringState(cx);        /* Clear debugging state to remove GC roots. */        JS_ClearAllTraps(cx);        JS_ClearAllWatchPoints(cx);    }#if JS_HAS_REGEXPS    /*     * Remove more GC roots in regExpStatics, then collect garbage.     * XXX anti-modularity alert: we rely on the call to js_RemoveRoot within     * XXX this function call to wait for any racing GC to complete, in the     * XXX case where JS_DestroyContext is called outside of a request on cx     */    js_FreeRegExpStatics(cx, &cx->regExpStatics);#endif#ifdef JS_THREADSAFE    /*     * Destroying a context implicitly calls JS_EndRequest().  Also, we must     * end our request here in case we are "last" -- in that event, another     * js_DestroyContext that was not last might be waiting in the GC for our     * request to end.  We'll let it run below, just before we do the truly     * final GC and then free atom state.     *     * At this point, cx must be inaccessible to other threads.  It's off the     * rt->contextList, and it should not be reachable via any object private     * data structure.     */    while (cx->requestDepth != 0)        JS_EndRequest(cx);#endif    if (last) {        /* Always force, so we wait for any racing GC to finish. */        js_ForceGC(cx, GC_LAST_CONTEXT);        /* Iterate until no finalizer removes a GC root or lock. */        while (rt->gcPoke)            js_GC(cx, GC_LAST_CONTEXT);        /* Try to free atom state, now that no unrooted scripts survive. */        if (rt->atomState.liveAtoms == 0)            js_FreeAtomState(cx, &rt->atomState);        /* Now after the last GC can we free the script filename table. */        js_FinishRuntimeScriptState(cx);        /* Take the runtime down, now that it has no contexts or atoms. */        JS_LOCK_GC(rt);        rt->state = JSRTS_DOWN;        JS_NOTIFY_ALL_CONDVAR(rt->stateChange);        JS_UNLOCK_GC(rt);    } else {        if (gcmode == JS_FORCE_GC)            js_ForceGC(cx, 0);        else if (gcmode == JS_MAYBE_GC)            JS_MaybeGC(cx);    }    /* Free the stuff hanging off of cx. */    JS_FinishArenaPool(&cx->stackPool);    JS_FinishArenaPool(&cx->tempPool);    if (cx->lastMessage)        free(cx->lastMessage);    /* Remove any argument formatters. */    map = cx->argumentFormatMap;    while (map) {        JSArgumentFormatMap *temp = map;        map = map->next;        JS_free(cx, temp);    }    /* Destroy the resolve recursion damper. */    if (cx->resolvingTable) {        JS_DHashTableDestroy(cx->resolvingTable);        cx->resolvingTable = NULL;    }    /* Finally, free cx itself. */    free(cx);}JSBooljs_ValidContextPointer(JSRuntime *rt, JSContext *cx){    JSCList *cl;    for (cl = rt->contextList.next; cl != &rt->contextList; cl = cl->next) {        if (cl == &cx->links)            return JS_TRUE;    }    JS_RUNTIME_METER(rt, deadContexts);    return JS_FALSE;}JSContext *js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp){    JSContext *cx = *iterp;    if (unlocked)        JS_LOCK_GC(rt);    if (!cx)        cx = (JSContext *)&rt->contextList;    cx = (JSContext *)cx->links.next;    if (&cx->links == &rt->contextList)        cx = NULL;    *iterp = cx;    if (unlocked)        JS_UNLOCK_GC(rt);    return cx;}static voidReportError(JSContext *cx, const char *message, JSErrorReport *reportp){    /*     * Check the error report, and set a JavaScript-catchable exception     * if the error is defined to have an associated exception.  If an     * exception is thrown, then the JSREPORT_EXCEPTION flag will be set     * on the error report, and exception-aware hosts should ignore it.     */    if (reportp && reportp->errorNumber == JSMSG_UNCAUGHT_EXCEPTION)        reportp->flags |= JSREPORT_EXCEPTION;#if JS_HAS_ERROR_EXCEPTIONS    /*     * Call the error reporter only if an exception wasn't raised.     *     * If an exception was raised, then we call the debugErrorHook     * (if present) to give it a chance to see the error before it     * propagates out of scope.  This is needed for compatability     * with the old scheme.     */    if (!js_ErrorToException(cx, message, reportp)) {        js_ReportErrorAgain(cx, message, reportp);    } else if (cx->runtime->debugErrorHook && cx->errorReporter) {        JSDebugErrorHook hook = cx->runtime->debugErrorHook;        /* test local in case debugErrorHook changed on another thread */        if (hook)            hook(cx, message, reportp, cx->runtime->debugErrorHookData);    }#else    js_ReportErrorAgain(cx, message, reportp);#endif}/* * We don't post an exception in this case, since doing so runs into * complications of pre-allocating an exception object which required * running the Exception class initializer early etc. * Instead we just invoke the errorReporter with an "Out Of Memory" * type message, and then hope the process ends swiftly. */void

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -