jsscript.c

来自「java script test programing source code」· C语言 代码 · 共 1,718 行 · 第 1/4 页

C
1,718
字号
    /* Swap script for obj's old script, if any. */    v = LOCKED_OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);    oldscript = !JSVAL_IS_VOID(v) ? (JSScript *) JSVAL_TO_PRIVATE(v) : NULL;    LOCKED_OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(script));    JS_UNLOCK_OBJ(cx, obj);    if (oldscript)        js_DestroyScript(cx, oldscript);    script->object = obj;    js_CallNewScriptHook(cx, script, NULL);out:    /*     * We reset the buffer to be NULL so that it doesn't free the chars     * memory owned by str (argv[0]).     */    JS_XDRMemSetData(xdr, NULL, 0);    JS_XDRDestroy(xdr);#if IS_BIG_ENDIAN    JS_free(cx, buf);#endif    *rval = JSVAL_TRUE;    return ok;}static const char js_thaw_str[] = "thaw";#endif /* JS_HAS_XDR_FREEZE_THAW */#endif /* JS_HAS_XDR */static JSFunctionSpec script_methods[] = {#if JS_HAS_TOSOURCE    {js_toSource_str,   script_toSource,        0,0,0},#endif    {js_toString_str,   script_toString,        0,0,0},    {"compile",         script_compile,         2,0,0},    {"exec",            script_exec,            1,0,0},#if JS_HAS_XDR_FREEZE_THAW    {"freeze",          script_freeze,          0,0,0},    {js_thaw_str,       script_thaw,            1,0,0},#endif /* JS_HAS_XDR_FREEZE_THAW */    {0,0,0,0,0}};#endif /* JS_HAS_SCRIPT_OBJECT */static voidscript_finalize(JSContext *cx, JSObject *obj){    JSScript *script;    script = (JSScript *) JS_GetPrivate(cx, obj);    if (script)        js_DestroyScript(cx, script);}static JSBoolscript_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){#if JS_HAS_SCRIPT_OBJECT    return script_exec(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval);#else    return JS_FALSE;#endif}static uint32script_mark(JSContext *cx, JSObject *obj, void *arg){    JSScript *script;    script = (JSScript *) JS_GetPrivate(cx, obj);    if (script)        js_MarkScript(cx, script);    return 0;}#if !JS_HAS_SCRIPT_OBJECTconst char js_Script_str[] = "Script";#define JSProto_Script  JSProto_Object#endifJS_FRIEND_DATA(JSClass) js_ScriptClass = {    js_Script_str,    JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Script) |    JSCLASS_HAS_RESERVED_SLOTS(1),    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,    JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   script_finalize,    NULL,             NULL,             script_call,      NULL,/*XXXbe xdr*/    NULL,             NULL,             script_mark,      0};#if JS_HAS_SCRIPT_OBJECTstatic JSBoolScript(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    /* If not constructing, replace obj with a new Script object. */    if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {        obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);        if (!obj)            return JS_FALSE;        /*         * script_compile does not use rval to root its temporaries         * so we can use it to root obj.         */        *rval = OBJECT_TO_JSVAL(obj);    }    if (!JS_SetReservedSlot(cx, obj, 0, INT_TO_JSVAL(0)))        return JS_FALSE;    return script_compile(cx, obj, argc, argv, rval);}#if JS_HAS_XDR_FREEZE_THAWstatic JSBoolscript_static_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,                   jsval *rval){    obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);    if (!obj)        return JS_FALSE;    if (!script_thaw(cx, obj, argc, argv, rval))        return JS_FALSE;    *rval = OBJECT_TO_JSVAL(obj);    return JS_TRUE;}static JSFunctionSpec script_static_methods[] = {    {js_thaw_str,       script_static_thaw,     1,0,0},    {0,0,0,0,0}};#else  /* !JS_HAS_XDR_FREEZE_THAW */#define script_static_methods   NULL#endif /* !JS_HAS_XDR_FREEZE_THAW */JSObject *js_InitScriptClass(JSContext *cx, JSObject *obj){    return JS_InitClass(cx, obj, NULL, &js_ScriptClass, Script, 1,                        NULL, script_methods, NULL, script_static_methods);}#endif /* JS_HAS_SCRIPT_OBJECT *//* * Shared script filename management. */JS_STATIC_DLL_CALLBACK(int)js_compare_strings(const void *k1, const void *k2){    return strcmp(k1, k2) == 0;}/* Shared with jsatom.c to save code space. */extern void * JS_DLL_CALLBACKjs_alloc_table_space(void *priv, size_t size);extern void JS_DLL_CALLBACKjs_free_table_space(void *priv, void *item);/* NB: This struct overlays JSHashEntry -- see jshash.h, do not reorganize. */typedef struct ScriptFilenameEntry {    JSHashEntry         *next;          /* hash chain linkage */    JSHashNumber        keyHash;        /* key hash function result */    const void          *key;           /* ptr to filename, below */    uint32              flags;          /* user-defined filename prefix flags */    JSPackedBool        mark;           /* GC mark flag */    char                filename[3];    /* two or more bytes, NUL-terminated */} ScriptFilenameEntry;JS_STATIC_DLL_CALLBACK(JSHashEntry *)js_alloc_sftbl_entry(void *priv, const void *key){    size_t nbytes = offsetof(ScriptFilenameEntry, filename) + strlen(key) + 1;    return (JSHashEntry *) malloc(JS_MAX(nbytes, sizeof(JSHashEntry)));}JS_STATIC_DLL_CALLBACK(void)js_free_sftbl_entry(void *priv, JSHashEntry *he, uintN flag){    if (flag != HT_FREE_ENTRY)        return;    free(he);}static JSHashAllocOps sftbl_alloc_ops = {    js_alloc_table_space,   js_free_table_space,    js_alloc_sftbl_entry,   js_free_sftbl_entry};JSBooljs_InitRuntimeScriptState(JSRuntime *rt){#ifdef JS_THREADSAFE    JS_ASSERT(!rt->scriptFilenameTableLock);    rt->scriptFilenameTableLock = JS_NEW_LOCK();    if (!rt->scriptFilenameTableLock)        return JS_FALSE;#endif    JS_ASSERT(!rt->scriptFilenameTable);    rt->scriptFilenameTable =        JS_NewHashTable(16, JS_HashString, js_compare_strings, NULL,                        &sftbl_alloc_ops, NULL);    if (!rt->scriptFilenameTable) {        js_FinishRuntimeScriptState(rt);    /* free lock if threadsafe */        return JS_FALSE;    }    JS_INIT_CLIST(&rt->scriptFilenamePrefixes);    return JS_TRUE;}typedef struct ScriptFilenamePrefix {    JSCList     links;      /* circular list linkage for easy deletion */    const char  *name;      /* pointer to pinned ScriptFilenameEntry string */    size_t      length;     /* prefix string length, precomputed */    uint32      flags;      /* user-defined flags to inherit from this prefix */} ScriptFilenamePrefix;voidjs_FinishRuntimeScriptState(JSRuntime *rt){    if (rt->scriptFilenameTable) {        JS_HashTableDestroy(rt->scriptFilenameTable);        rt->scriptFilenameTable = NULL;    }#ifdef JS_THREADSAFE    if (rt->scriptFilenameTableLock) {        JS_DESTROY_LOCK(rt->scriptFilenameTableLock);        rt->scriptFilenameTableLock = NULL;    }#endif}voidjs_FreeRuntimeScriptState(JSRuntime *rt){    ScriptFilenamePrefix *sfp;    if (!rt->scriptFilenameTable)        return;    while (!JS_CLIST_IS_EMPTY(&rt->scriptFilenamePrefixes)) {        sfp = (ScriptFilenamePrefix *) rt->scriptFilenamePrefixes.next;        JS_REMOVE_LINK(&sfp->links);        free(sfp);    }    js_FinishRuntimeScriptState(rt);}#ifdef DEBUG_brendan#define DEBUG_SFTBL#endif#ifdef DEBUG_SFTBLsize_t sftbl_savings = 0;#endifstatic ScriptFilenameEntry *SaveScriptFilename(JSRuntime *rt, const char *filename, uint32 flags){    JSHashTable *table;    JSHashNumber hash;    JSHashEntry **hep;    ScriptFilenameEntry *sfe;    size_t length;    JSCList *head, *link;    ScriptFilenamePrefix *sfp;    table = rt->scriptFilenameTable;    hash = JS_HashString(filename);    hep = JS_HashTableRawLookup(table, hash, filename);    sfe = (ScriptFilenameEntry *) *hep;#ifdef DEBUG_SFTBL    if (sfe)        sftbl_savings += strlen(sfe->filename);#endif    if (!sfe) {        sfe = (ScriptFilenameEntry *)              JS_HashTableRawAdd(table, hep, hash, filename, NULL);        if (!sfe)            return NULL;        sfe->key = strcpy(sfe->filename, filename);        sfe->flags = 0;        sfe->mark = JS_FALSE;    }    /* If saving a prefix, add it to the set in rt->scriptFilenamePrefixes. */    if (flags != 0) {        /* Search in case filename was saved already; we must be idempotent. */        sfp = NULL;        length = strlen(filename);        for (head = link = &rt->scriptFilenamePrefixes;             link->next != head;             link = link->next) {            /* Lag link behind sfp to insert in non-increasing length order. */            sfp = (ScriptFilenamePrefix *) link->next;            if (!strcmp(sfp->name, filename))                break;            if (sfp->length <= length) {                sfp = NULL;                break;            }            sfp = NULL;        }        if (!sfp) {            /* No such prefix: add one now. */            sfp = (ScriptFilenamePrefix *) malloc(sizeof(ScriptFilenamePrefix));            if (!sfp)                return NULL;            JS_INSERT_AFTER(&sfp->links, link);            sfp->name = sfe->filename;            sfp->length = length;            sfp->flags = 0;        }        /*         * Accumulate flags in both sfe and sfp: sfe for later access from the         * JS_GetScriptedCallerFilenameFlags debug-API, and sfp so that longer         * filename entries can inherit by prefix.         */        sfe->flags |= flags;        sfp->flags |= flags;    }    return sfe;}const char *js_SaveScriptFilename(JSContext *cx, const char *filename){    JSRuntime *rt;    ScriptFilenameEntry *sfe;    JSCList *head, *link;    ScriptFilenamePrefix *sfp;    rt = cx->runtime;    JS_ACQUIRE_LOCK(rt->scriptFilenameTableLock);    sfe = SaveScriptFilename(rt, filename, 0);    if (!sfe) {        JS_RELEASE_LOCK(rt->scriptFilenameTableLock);        JS_ReportOutOfMemory(cx);        return NULL;    }    /*     * Try to inherit flags by prefix.  We assume there won't be more than a     * few (dozen! ;-) prefixes, so linear search is tolerable.     * XXXbe every time I've assumed that in the JS engine, I've been wrong!     */    for (head = &rt->scriptFilenamePrefixes, link = head->next;         link != head;         link = link->next) {        sfp = (ScriptFilenamePrefix *) link;        if (!strncmp(sfp->name, filename, sfp->length)) {            sfe->flags |= sfp->flags;            break;        }    }    JS_RELEASE_LOCK(rt->scriptFilenameTableLock);    return sfe->filename;}const char *js_SaveScriptFilenameRT(JSRuntime *rt, const char *filename, uint32 flags){    ScriptFilenameEntry *sfe;    /* This may be called very early, via the jsdbgapi.h entry point. */    if (!rt->scriptFilenameTable && !js_InitRuntimeScriptState(rt))        return NULL;    JS_ACQUIRE_LOCK(rt->scriptFilenameTableLock);    sfe = SaveScriptFilename(rt, filename, flags);    JS_RELEASE_LOCK(rt->scriptFilenameTableLock);    if (!sfe)        return NULL;    return sfe->filename;}/* * Back up from a saved filename by its offset within its hash table entry. */#define FILENAME_TO_SFE(fn) \    ((ScriptFilenameEntry *) ((fn) - offsetof(ScriptFilenameEntry, filename)))/* * The sfe->key member, redundant given sfe->filename but required by the old * jshash.c code, here gives us a useful sanity check.  This assertion will * very likely botch if someone tries to mark a string that wasn't allocated * as an sfe->filename. */#define ASSERT_VALID_SFE(sfe)   JS_ASSERT((sfe)->key == (sfe)->filename)uint32js_GetScriptFilenameFlags(const char *filename){    ScriptFilenameEntry *sfe;    sfe = FILENAME_TO_SFE(filename);    ASSERT_VALID_SFE(sfe);    return sfe->flags;}voidjs_MarkScriptFilename(const char *filename){    ScriptFilenameEntry *sfe;    sfe = FILENAME_TO_SFE(filename);    ASSERT_VALID_SFE(sfe);    sfe->mark = JS_TRUE;}JS_STATIC_DLL_CALLBACK(intN)js_script_filename_marker(JSHashEntry *he, intN i, void *arg){    ScriptFilenameEntry *sfe = (ScriptFilenameEntry *) he;

⌨️ 快捷键说明

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