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

📄 jsatom.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 atom table. */#include "jsstddef.h"#include <stdlib.h>#include <string.h>#include "jstypes.h"#include "jsutil.h" /* Added by JSIFY */#include "jshash.h" /* Added by JSIFY */#include "jsprf.h"#include "jsapi.h"#include "jsatom.h"#include "jscntxt.h"#include "jsgc.h"#include "jslock.h"#include "jsnum.h"#include "jsopcode.h"#include "jsstr.h"JS_FRIEND_API(const char *)js_AtomToPrintableString(JSContext *cx, JSAtom *atom){    JSString *str;    const char *bytes;    str = js_QuoteString(cx, ATOM_TO_STRING(atom), 0);    if (!str)        return NULL;    bytes = js_GetStringBytes(str);    if (!bytes)        JS_ReportOutOfMemory(cx);    return bytes;}extern const char js_Error_str[];       /* trivial, from jsexn.h *//* * Keep this in sync with jspubtd.h -- an assertion below will insist that * its length match the JSType enum's JSTYPE_LIMIT limit value. */const char *js_type_str[] = {    "undefined",    "object",    "function",    "string",    "number",    "boolean",};const char *js_boolean_str[] = {    js_false_str,    js_true_str};const char js_Arguments_str[]       = "Arguments";const char js_Array_str[]           = "Array";const char js_Boolean_str[]         = "Boolean";const char js_Call_str[]            = "Call";const char js_Date_str[]            = "Date";const char js_Function_str[]        = "Function";const char js_Math_str[]            = "Math";const char js_Number_str[]          = "Number";const char js_Object_str[]          = "Object";const char js_RegExp_str[]          = "RegExp";const char js_Script_str[]          = "Script";const char js_String_str[]          = "String";const char js_anonymous_str[]       = "anonymous";const char js_arguments_str[]       = "arguments";const char js_arity_str[]           = "arity";const char js_callee_str[]          = "callee";const char js_caller_str[]          = "caller";const char js_class_prototype_str[] = "prototype";const char js_constructor_str[]     = "constructor";const char js_count_str[]           = "__count__";const char js_eval_str[]            = "eval";const char js_getter_str[]          = "getter";const char js_get_str[]             = "get";const char js_index_str[]           = "index";const char js_input_str[]           = "input";const char js_length_str[]          = "length";const char js_name_str[]            = "name";const char js_noSuchMethod_str[]    = "__noSuchMethod__";const char js_parent_str[]          = "__parent__";const char js_proto_str[]           = "__proto__";const char js_setter_str[]          = "setter";const char js_set_str[]             = "set";const char js_toSource_str[]        = "toSource";const char js_toString_str[]        = "toString";const char js_toLocaleString_str[]  = "toLocaleString";const char js_valueOf_str[]         = "valueOf";#ifdef NARCISSUSconst char js_call_str[]             = "__call__";const char js_construct_str[]        = "__construct__";const char js_hasInstance_str[]      = "__hasInstance__";const char js_ExecutionContext_str[] = "ExecutionContext";const char js_current_str[]          = "current";#endif#define HASH_OBJECT(o)  ((JSHashNumber)(JS_PTR_TO_UINT32(o) >> JSVAL_TAGBITS))#define HASH_INT(i)     ((JSHashNumber)(i))#define HASH_DOUBLE(dp) ((JSHashNumber)(JSDOUBLE_HI32(*dp) ^ JSDOUBLE_LO32(*dp)))#define HASH_BOOLEAN(b) ((JSHashNumber)(b))JS_STATIC_DLL_CALLBACK(JSHashNumber)js_hash_atom_key(const void *key){    jsval v;    jsdouble *dp;    /* Order JSVAL_IS_* tests by likelihood of success. */    v = (jsval)key;    if (JSVAL_IS_STRING(v))        return js_HashString(JSVAL_TO_STRING(v));    if (JSVAL_IS_INT(v))        return HASH_INT(JSVAL_TO_INT(v));    if (JSVAL_IS_DOUBLE(v)) {        dp = JSVAL_TO_DOUBLE(v);        return HASH_DOUBLE(dp);    }    if (JSVAL_IS_OBJECT(v))        return HASH_OBJECT(JSVAL_TO_OBJECT(v));    if (JSVAL_IS_BOOLEAN(v))        return HASH_BOOLEAN(JSVAL_TO_BOOLEAN(v));    return (JSHashNumber)v;}JS_STATIC_DLL_CALLBACK(intN)js_compare_atom_keys(const void *k1, const void *k2){    jsval v1, v2;    v1 = (jsval)k1, v2 = (jsval)k2;    if (JSVAL_IS_STRING(v1) && JSVAL_IS_STRING(v2))        return !js_CompareStrings(JSVAL_TO_STRING(v1), JSVAL_TO_STRING(v2));    if (JSVAL_IS_DOUBLE(v1) && JSVAL_IS_DOUBLE(v2)) {        double d1 = *JSVAL_TO_DOUBLE(v1);        double d2 = *JSVAL_TO_DOUBLE(v2);        if (JSDOUBLE_IS_NaN(d1))            return JSDOUBLE_IS_NaN(d2);#if defined(XP_WIN)        /* XXX MSVC miscompiles such that (NaN == 0) */        if (JSDOUBLE_IS_NaN(d2))            return JS_FALSE;#endif        return (d1 - d2) < 0.00000001;    }    return v1 == v2;}intNjs_compare_atom_keys_no_case(const void *k1, const void *k2){    jsval v1, v2;    v1 = (jsval)k1, v2 = (jsval)k2;    if (JSVAL_IS_STRING(v1) && JSVAL_IS_STRING(v2))        return !js_CompareStringsNoCase(JSVAL_TO_STRING(v1), JSVAL_TO_STRING(v2));    return js_compare_atom_keys (k1, k2);}JS_STATIC_DLL_CALLBACK(int)js_compare_stub(const void *v1, const void *v2){    return 1;}/* These next two are exported to jsscript.c and used similarly there. */void * JS_DLL_CALLBACKjs_alloc_table_space(void *priv, size_t size){    return malloc(size);}void JS_DLL_CALLBACKjs_free_table_space(void *priv, void *item){    free(item);}JS_STATIC_DLL_CALLBACK(JSHashEntry *)js_alloc_atom(void *priv, const void *key){    JSAtomState *state = (JSAtomState *) priv;    JSAtom *atom;    atom = (JSAtom *) malloc(sizeof(JSAtom));    if (!atom)        return NULL;#ifdef JS_THREADSAFE    state->tablegen++;#endif    atom->entry.key = key;    atom->entry.value = NULL;    atom->flags = 0;    atom->number = state->number++;    return &atom->entry;}JS_STATIC_DLL_CALLBACK(void)js_free_atom(void *priv, JSHashEntry *he, uintN flag){    if (flag != HT_FREE_ENTRY)        return;#ifdef JS_THREADSAFE    ((JSAtomState *)priv)->tablegen++;#endif    free(he);}static JSHashAllocOps atom_alloc_ops = {    js_alloc_table_space,   js_free_table_space,    js_alloc_atom,          js_free_atom};#define JS_ATOM_HASH_SIZE   1024JSBooljs_InitAtomState(JSContext *cx, JSAtomState *state){    state->table = JS_NewHashTable(JS_ATOM_HASH_SIZE, js_hash_atom_key,                                   js_compare_atom_keys, js_compare_stub,                                   &atom_alloc_ops, state);    if (!state->table) {        JS_ReportOutOfMemory(cx);        return JS_FALSE;    }    state->runtime = cx->runtime;#ifdef JS_THREADSAFE    js_InitLock(&state->lock);    state->tablegen = 0;#endif    if (!js_InitPinnedAtoms(cx, state)) {        js_FreeAtomState(cx, state);        return JS_FALSE;    }    return JS_TRUE;}JSBooljs_InitPinnedAtoms(JSContext *cx, JSAtomState *state){    uintN i;#define FROB(lval,str)                                                        \    JS_BEGIN_MACRO                                                            \        if (!(state->lval = js_Atomize(cx, str, strlen(str), ATOM_PINNED)))   \            return JS_FALSE;                                                  \    JS_END_MACRO    JS_ASSERT(sizeof js_type_str / sizeof js_type_str[0] == JSTYPE_LIMIT);    for (i = 0; i < JSTYPE_LIMIT; i++)        FROB(typeAtoms[i],        js_type_str[i]);    FROB(booleanAtoms[0],         js_false_str);    FROB(booleanAtoms[1],         js_true_str);    FROB(nullAtom,                js_null_str);    FROB(ArgumentsAtom,           js_Arguments_str);    FROB(ArrayAtom,               js_Array_str);    FROB(BooleanAtom,             js_Boolean_str);    FROB(CallAtom,                js_Call_str);    FROB(DateAtom,                js_Date_str);    FROB(ErrorAtom,               js_Error_str);    FROB(FunctionAtom,            js_Function_str);    FROB(MathAtom,                js_Math_str);    FROB(NumberAtom,              js_Number_str);    FROB(ObjectAtom,              js_Object_str);    FROB(RegExpAtom,              js_RegExp_str);    FROB(ScriptAtom,              js_Script_str);    FROB(StringAtom,              js_String_str);    FROB(anonymousAtom,           js_anonymous_str);    FROB(argumentsAtom,           js_arguments_str);    FROB(arityAtom,               js_arity_str);    FROB(calleeAtom,              js_callee_str);    FROB(callerAtom,              js_caller_str);    FROB(classPrototypeAtom,      js_class_prototype_str);    FROB(constructorAtom,         js_constructor_str);    FROB(countAtom,               js_count_str);    FROB(evalAtom,                js_eval_str);    FROB(getAtom,                 js_get_str);    FROB(getterAtom,              js_getter_str);    FROB(indexAtom,               js_index_str);    FROB(inputAtom,               js_input_str);    FROB(lengthAtom,              js_length_str);    FROB(nameAtom,                js_name_str);    FROB(noSuchMethodAtom,        js_noSuchMethod_str);    FROB(parentAtom,              js_parent_str);    FROB(protoAtom,               js_proto_str);    FROB(setAtom,                 js_set_str);    FROB(setterAtom,              js_setter_str);    FROB(toSourceAtom,            js_toSource_str);    FROB(toStringAtom,            js_toString_str);    FROB(toLocaleStringAtom,      js_toLocaleString_str);    FROB(valueOfAtom,             js_valueOf_str);#ifdef NARCISSUS    FROB(callAtom,                js_call_str);    FROB(constructAtom,           js_construct_str);    FROB(hasInstanceAtom,         js_hasInstance_str);    FROB(ExecutionContextAtom,    js_ExecutionContext_str);    FROB(currentAtom,             js_current_str);#endif#undef FROB    memset(&state->lazy, 0, sizeof state->lazy);    return JS_TRUE;}/* NB: cx unused; js_FinishAtomState calls us with null cx. */voidjs_FreeAtomState(JSContext *cx, JSAtomState *state){    if (state->table)        JS_HashTableDestroy(state->table);#ifdef JS_THREADSAFE    js_FinishLock(&state->lock);#endif    memset(state, 0, sizeof *state);}typedef struct UninternArgs {    JSRuntime   *rt;    jsatomid    leaks;} UninternArgs;JS_STATIC_DLL_CALLBACK(intN)js_atom_uninterner(JSHashEntry *he, intN i, void *arg){    JSAtom *atom;    UninternArgs *args;    atom = (JSAtom *)he;    args = (UninternArgs *)arg;    if (ATOM_IS_STRING(atom))        js_FinalizeStringRT(args->rt, ATOM_TO_STRING(atom));    else if (ATOM_IS_OBJECT(atom))        args->leaks++;    return HT_ENUMERATE_NEXT;}voidjs_FinishAtomState(JSAtomState *state){    UninternArgs args;    if (!state->table)        return;    args.rt = state->runtime;    args.leaks = 0;    JS_HashTableEnumerateEntries(state->table, js_atom_uninterner, &args);#ifdef DEBUG    if (args.leaks != 0) {        fprintf(stderr,"JS engine warning: %lu atoms remain after destroying the JSRuntime.\n""                   These atoms may point to freed memory. Things reachable\n""                   through them have not been finalized.\n",                (unsigned long) args.leaks);    }#endif    js_FreeAtomState(NULL, state);}typedef struct MarkArgs {    uintN           gcflags;    JSGCThingMarker mark;    void            *data;} MarkArgs;JS_STATIC_DLL_CALLBACK(intN)js_atom_marker(JSHashEntry *he, intN i, void *arg){    JSAtom *atom;    MarkArgs *args;    jsval key;    atom = (JSAtom *)he;    args = (MarkArgs *)arg;    if ((atom->flags & (ATOM_PINNED | ATOM_INTERNED)) ||        (args->gcflags & GC_KEEP_ATOMS)) {        atom->flags |= ATOM_MARK;        key = ATOM_KEY(atom);        if (JSVAL_IS_GCTHING(key))            args->mark(JSVAL_TO_GCTHING(key), args->data);    }    return HT_ENUMERATE_NEXT;}voidjs_MarkAtomState(JSAtomState *state, uintN gcflags, JSGCThingMarker mark,                 void *data){    MarkArgs args;    if (!state->table)        return;    args.gcflags = gcflags;    args.mark = mark;    args.data = data;    JS_HashTableEnumerateEntries(state->table, js_atom_marker, &args);}JS_STATIC_DLL_CALLBACK(intN)js_atom_sweeper(JSHashEntry *he, intN i, void *arg){    JSAtom *atom;    JSAtomState *state;    atom = (JSAtom *)he;    if (atom->flags & ATOM_MARK) {        atom->flags &= ~ATOM_MARK;        state = (JSAtomState *)arg;        state->liveAtoms++;        return HT_ENUMERATE_NEXT;    }    JS_ASSERT((atom->flags & (ATOM_PINNED | ATOM_INTERNED)) == 0);    atom->entry.key = NULL;    atom->flags = 0;    return HT_ENUMERATE_REMOVE;}voidjs_SweepAtomState(JSAtomState *state){    state->liveAtoms = 0;    if (state->table)        JS_HashTableEnumerateEntries(state->table, js_atom_sweeper, state);}JS_STATIC_DLL_CALLBACK(intN)js_atom_unpinner(JSHashEntry *he, intN i, void *arg){    JSAtom *atom;

⌨️ 快捷键说明

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