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

📄 jscntxt.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=8 sw=4 et tw=80: * * ***** 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 "jsscope.h"#include "jsscript.h"#include "jsstr.h"#ifdef JS_THREADSAFE/* * Callback function to delete a JSThread info when the thread that owns it * is destroyed. */void JS_DLL_CALLBACKjs_ThreadDestructorCB(void *ptr){    JSThread *thread = (JSThread *)ptr;    if (!thread)        return;    while (!JS_CLIST_IS_EMPTY(&thread->contextList)) {        /* NB: use a temporary, as the macro evaluates its args many times. */        JSCList *link = thread->contextList.next;        JS_REMOVE_AND_INIT_LINK(link);    }    GSN_CACHE_CLEAR(&thread->gsnCache);    free(thread);}/* * Get current thread-local JSThread info, creating one if it doesn't exist. * Each thread has a unique JSThread pointer. * * Since we are dealing with thread-local data, no lock is needed. * * Return a pointer to the thread local info, NULL if the system runs out * of memory, or it failed to set thread private data (neither case is very * likely; both are probably due to out-of-memory).  It is up to the caller * to report an error, if possible. */JSThread *js_GetCurrentThread(JSRuntime *rt){    JSThread *thread;    thread = (JSThread *)PR_GetThreadPrivate(rt->threadTPIndex);    if (!thread) {        thread = (JSThread *) calloc(1, sizeof(JSThread));        if (!thread)            return NULL;        if (PR_FAILURE == PR_SetThreadPrivate(rt->threadTPIndex, thread)) {            free(thread);            return NULL;        }        JS_INIT_CLIST(&thread->contextList);        thread->id = js_CurrentThreadId();        /* js_SetContextThread initialize gcFreeLists as necessary. */#ifdef DEBUG        memset(thread->gcFreeLists, JS_FREE_PATTERN,               sizeof(thread->gcFreeLists));#endif    }    return thread;}/* * Sets current thread as owning thread of a context by assigning the * thread-private info to the context. If the current thread doesn't have * private JSThread info, create one. */JSBooljs_SetContextThread(JSContext *cx){    JSThread *thread = js_GetCurrentThread(cx->runtime);    if (!thread) {        JS_ReportOutOfMemory(cx);        return JS_FALSE;    }    /*     * Clear gcFreeLists on each transition from 0 to 1 context active on the     * current thread. See bug 351602.     */    if (JS_CLIST_IS_EMPTY(&thread->contextList))        memset(thread->gcFreeLists, 0, sizeof(thread->gcFreeLists));    cx->thread = thread;    JS_REMOVE_LINK(&cx->threadLinks);    JS_APPEND_LINK(&cx->threadLinks, &thread->contextList);    return JS_TRUE;}/* Remove the owning thread info of a context. */voidjs_ClearContextThread(JSContext *cx){    JS_REMOVE_AND_INIT_LINK(&cx->threadLinks);#ifdef DEBUG    if (JS_CLIST_IS_EMPTY(&cx->thread->contextList)) {        memset(cx->thread->gcFreeLists, JS_FREE_PATTERN,               sizeof(cx->thread->gcFreeLists));    }#endif    cx->thread = NULL;}#endif /* JS_THREADSAFE */voidjs_OnVersionChange(JSContext *cx){#ifdef DEBUG    JSVersion version = JSVERSION_NUMBER(cx);    JS_ASSERT(version == JSVERSION_DEFAULT || version >= JSVERSION_ECMA_3);#endif}voidjs_SetVersion(JSContext *cx, JSVersion version){    cx->version = version;    js_OnVersionChange(cx);}JSContext *js_NewContext(JSRuntime *rt, size_t stackChunkSize){    JSContext *cx;    JSBool ok, first;    JSContextCallback cxCallback;    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_INIT_CLIST(&cx->threadLinks);    js_SetContextThread(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;    JS_InitArenaPool(&cx->stackPool, "stack", stackChunkSize, sizeof(jsval));    JS_InitArenaPool(&cx->tempPool, "temp", 1024, sizeof(jsdouble));    if (!js_InitRegExpStatics(cx, &cx->regExpStatics)) {        js_DestroyContext(cx, JSDCM_NEW_FAILED);        return NULL;    }    /*     * 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) {#ifdef JS_THREADSAFE        JS_BeginRequest(cx);#endif        /*         * Both atomState and the scriptFilenameTable may be left over from a         * previous episode of non-zero contexts alive in rt, so don't re-init         * either table if it's not necessary.  Just repopulate atomState with         * well-known internal atoms, and with the reserved identifiers added         * by the scanner.         */        ok = (rt->atomState.liveAtoms == 0)             ? js_InitAtomState(cx, &rt->atomState)             : js_InitPinnedAtoms(cx, &rt->atomState);        if (ok && !rt->scriptFilenameTable)            ok = js_InitRuntimeScriptState(rt);        if (ok)            ok = js_InitRuntimeNumberState(cx);        if (ok)            ok = js_InitRuntimeStringState(cx);#ifdef JS_THREADSAFE        JS_EndRequest(cx);#endif        if (!ok) {            js_DestroyContext(cx, JSDCM_NEW_FAILED);            return NULL;        }        JS_LOCK_GC(rt);        rt->state = JSRTS_UP;        JS_NOTIFY_ALL_CONDVAR(rt->stateChange);        JS_UNLOCK_GC(rt);    }    cxCallback = rt->cxCallback;    if (cxCallback && !cxCallback(cx, JSCONTEXT_NEW)) {        js_DestroyContext(cx, JSDCM_NEW_FAILED);        return NULL;    }    return cx;}voidjs_DestroyContext(JSContext *cx, JSDestroyContextMode mode){    JSRuntime *rt;    JSContextCallback cxCallback;    JSBool last;    JSArgumentFormatMap *map;    JSLocalRootStack *lrs;    JSLocalRootChunk *lrc;    rt = cx->runtime;    if (mode != JSDCM_NEW_FAILED) {        cxCallback = rt->cxCallback;        if (cxCallback) {            /*             * JSCONTEXT_DESTROY callback is not allowed to fail and must             * return true.             */#ifdef DEBUG            JSBool callbackStatus =#endif            cxCallback(cx, JSCONTEXT_DESTROY);            JS_ASSERT(callbackStatus);        }    }    /* 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);    }    /*     * 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);#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) {        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);        /* Also free the script filename table if it exists and is empty. */        if (rt->scriptFilenameTable && rt->scriptFilenameTable->nentries == 0)            js_FinishRuntimeScriptState(rt);        /*         * Free the deflated string cache, but only after the last GC has         * collected all unleaked strings.         */        js_FinishDeflatedStringCache(rt);        /* 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 (mode == JSDCM_FORCE_GC)            js_GC(cx, GC_NORMAL);        else if (mode == JSDCM_MAYBE_GC)

⌨️ 快捷键说明

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