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

📄 jsscript.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 3 页
字号:
#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 */    JSPackedBool        mark;           /* mark flag, for GC */    char                filename[3];    /* two or more bytes, NUL-terminated */} ScriptFilenameEntry;JS_STATIC_DLL_CALLBACK(JSHashEntry *)js_alloc_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_entry(void *priv, JSHashEntry *he, uintN flag){    if (flag != HT_FREE_ENTRY)        return;    free(he);}static JSHashAllocOps table_alloc_ops = {    js_alloc_table_space,   js_free_table_space,    js_alloc_entry,         js_free_entry};JSBooljs_InitRuntimeScriptState(JSContext *cx){    JSRuntime *rt = cx->runtime;#ifdef JS_THREADSAFE    /* Must come through here once in primordial thread to init safely! */    if (!rt->scriptFilenameTableLock) {        rt->scriptFilenameTableLock = JS_NEW_LOCK();        if (!rt->scriptFilenameTableLock)            return JS_FALSE;    }#endif    if (!rt->scriptFilenameTable) {        JS_ACQUIRE_LOCK(rt->scriptFilenameTableLock);        if (!rt->scriptFilenameTable) {            rt->scriptFilenameTable =                JS_NewHashTable(16, JS_HashString, js_compare_strings, NULL,                                &table_alloc_ops, NULL);        }        JS_RELEASE_LOCK(rt->scriptFilenameTableLock);        if (!rt->scriptFilenameTable) {            js_FinishRuntimeScriptState(cx);    /* free lock if threadsafe */            return JS_FALSE;        }    }    return JS_TRUE;}voidjs_FinishRuntimeScriptState(JSContext *cx){    JSRuntime *rt = cx->runtime;    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}#ifdef DEBUG_brendansize_t sft_savings = 0;#endifconst char *js_SaveScriptFilename(JSContext *cx, const char *filename){    JSRuntime *rt = cx->runtime;    JSHashTable *table;    JSHashNumber hash;    JSHashEntry **hep;    ScriptFilenameEntry *sfe;    JS_ACQUIRE_LOCK(rt->scriptFilenameTableLock);    table = rt->scriptFilenameTable;    hash = JS_HashString(filename);    hep = JS_HashTableRawLookup(table, hash, filename);    sfe = (ScriptFilenameEntry *) *hep;#ifdef DEBUG_brendan    if (sfe)        sft_savings += strlen(sfe->filename);#endif    if (!sfe) {        sfe = (ScriptFilenameEntry *)              JS_HashTableRawAdd(table, hep, hash, filename, NULL);        if (sfe) {            sfe->key = strcpy(sfe->filename, filename);            JS_ASSERT(!sfe->mark);        }    }    JS_RELEASE_LOCK(rt->scriptFilenameTableLock);    if (!sfe) {        JS_ReportOutOfMemory(cx);        return NULL;    }    return sfe->filename;}voidjs_MarkScriptFilename(const char *filename){    ScriptFilenameEntry *sfe;    /*     * Back up from filename by its offset within its hash table entry.     * 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.     */    sfe = (ScriptFilenameEntry *)          (filename - offsetof(ScriptFilenameEntry, filename));    JS_ASSERT(sfe->key == sfe->filename);    sfe->mark = JS_TRUE;}JS_STATIC_DLL_CALLBACK(intN)js_script_filename_sweeper(JSHashEntry *he, intN i, void *arg){    ScriptFilenameEntry *sfe = (ScriptFilenameEntry *) he;    if (!sfe->mark)        return HT_ENUMERATE_REMOVE;    sfe->mark = JS_FALSE;    return HT_ENUMERATE_NEXT;}voidjs_SweepScriptFilenames(JSRuntime *rt){    JS_HashTableEnumerateEntries(rt->scriptFilenameTable,                                 js_script_filename_sweeper,                                 rt);#ifdef DEBUG_brendan    printf("script filename table savings so far: %u\n", sft_savings);#endif}JSScript *js_NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 ntrynotes){    JSScript *script;    /* Round up source note count to align script->trynotes for its type. */    if (ntrynotes)        nsrcnotes += JSTRYNOTE_ALIGNMASK;    script = (JSScript *) JS_malloc(cx,                                    sizeof(JSScript) +                                    length * sizeof(jsbytecode) +                                    nsrcnotes * sizeof(jssrcnote) +                                    ntrynotes * sizeof(JSTryNote));    if (!script)        return NULL;    memset(script, 0, sizeof(JSScript));    script->code = script->main = (jsbytecode *)(script + 1);    script->length = length;    script->version = cx->version;    if (ntrynotes) {        script->trynotes = (JSTryNote *)                           ((jsword)(SCRIPT_NOTES(script) + nsrcnotes) &                            ~(jsword)JSTRYNOTE_ALIGNMASK);    }    return script;}JS_FRIEND_API(JSScript *)js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun){    uint32 mainLength, prologLength, nsrcnotes, ntrynotes;    JSScript *script;    const char *filename;    mainLength = CG_OFFSET(cg);    prologLength = CG_PROLOG_OFFSET(cg);    CG_COUNT_FINAL_SRCNOTES(cg, nsrcnotes);    CG_COUNT_FINAL_TRYNOTES(cg, ntrynotes);    script = js_NewScript(cx, prologLength + mainLength, nsrcnotes, ntrynotes);    if (!script)        return NULL;    /* Now that we have script, error control flow must go to label bad. */    script->main += prologLength;    memcpy(script->code, CG_PROLOG_BASE(cg), prologLength * sizeof(jsbytecode));    memcpy(script->main, CG_BASE(cg), mainLength * sizeof(jsbytecode));    if (!js_InitAtomMap(cx, &script->atomMap, &cg->atomList))        goto bad;    filename = cg->filename;    if (filename) {        script->filename = js_SaveScriptFilename(cx, filename);        if (!script->filename)            goto bad;    }    script->lineno = cg->firstLine;    script->depth = cg->maxStackDepth;    if (cg->principals) {        script->principals = cg->principals;        JSPRINCIPALS_HOLD(cx, script->principals);    }    if (!js_FinishTakingSrcNotes(cx, cg, SCRIPT_NOTES(script)))        goto bad;    if (script->trynotes)        js_FinishTakingTryNotes(cx, cg, script->trynotes);    /* Tell the debugger about this compiled script. */    js_CallNewScriptHook(cx, script, fun);    return script;bad:    js_DestroyScript(cx, script);    return NULL;}JS_FRIEND_API(void)js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun){    JSRuntime *rt;    JSNewScriptHook hook;    rt = cx->runtime;    hook = rt->newScriptHook;    if (hook) {        /*         * We use a dummy stack frame to protect the script from a GC caused         * by debugger-hook execution.         *         * XXX We really need a way to manage local roots and such more         * XXX automatically, at which point we can remove this one-off hack         * XXX and others within the engine.  See bug 40757 for discussion.         */        JSStackFrame dummy;        memset(&dummy, 0, sizeof dummy);        dummy.down = cx->fp;        dummy.script = script;        cx->fp = &dummy;        hook(cx, script->filename, script->lineno, script, fun,             rt->newScriptHookData);        cx->fp = dummy.down;    }}voidjs_DestroyScript(JSContext *cx, JSScript *script){    JSRuntime *rt;    JSDestroyScriptHook hook;    rt = cx->runtime;    hook = rt->destroyScriptHook;    if (hook)        hook(cx, script, rt->destroyScriptHookData);    JS_ClearScriptTraps(cx, script);    js_FreeAtomMap(cx, &script->atomMap);    if (script->principals)        JSPRINCIPALS_DROP(cx, script->principals);    JS_free(cx, script);}voidjs_MarkScript(JSContext *cx, JSScript *script, void *arg){    JSAtomMap *map;    uintN i, length;    JSAtom **vector;    map = &script->atomMap;    length = map->length;    vector = map->vector;    for (i = 0; i < length; i++)        GC_MARK_ATOM(cx, vector[i], arg);    if (script->filename)        js_MarkScriptFilename(script->filename);}jssrcnote *js_GetSrcNote(JSScript *script, jsbytecode *pc){    jssrcnote *sn;    ptrdiff_t offset, target;    target = PTRDIFF(pc, script->code, jsbytecode);    if ((uint32)target >= script->length)        return NULL;    offset = 0;    for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {        offset += SN_DELTA(sn);        if (offset == target && SN_IS_GETTABLE(sn))            return sn;    }    return NULL;}uintNjs_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc){    JSAtom *atom;    JSFunction *fun;    uintN lineno;    ptrdiff_t offset, target;    jssrcnote *sn;    JSSrcNoteType type;    /*     * Special case: function definition needs no line number note because     * the function's script contains its starting line number.     */    if (*pc == JSOP_DEFFUN) {        atom = GET_ATOM(cx, script, pc);        fun = (JSFunction *) JS_GetPrivate(cx, ATOM_TO_OBJECT(atom));        return fun->script->lineno;    }    /*     * General case: walk through source notes accumulating their deltas,     * keeping track of line-number notes, until we pass the note for pc's     * offset within script->code.     */    lineno = script->lineno;    offset = 0;    target = PTRDIFF(pc, script->code, jsbytecode);    for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {        offset += SN_DELTA(sn);        type = (JSSrcNoteType) SN_TYPE(sn);        if (type == SRC_SETLINE) {            if (offset <= target)                lineno = (uintN) js_GetSrcNoteOffset(sn, 0);        } else if (type == SRC_NEWLINE) {            if (offset <= target)                lineno++;        }        if (offset > target)            break;    }    return lineno;}jsbytecode *js_LineNumberToPC(JSScript *script, uintN target){    ptrdiff_t offset;    uintN lineno;    jssrcnote *sn;    JSSrcNoteType type;    offset = 0;    lineno = script->lineno;    for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {        if (lineno >= target)            break;        offset += SN_DELTA(sn);        type = (JSSrcNoteType) SN_TYPE(sn);        if (type == SRC_SETLINE) {            lineno = (uintN) js_GetSrcNoteOffset(sn, 0);        } else if (type == SRC_NEWLINE) {            lineno++;        }    }    return script->code + offset;}uintNjs_GetScriptLineExtent(JSScript *script){    uintN lineno;    jssrcnote *sn;    JSSrcNoteType type;    lineno = script->lineno;    for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {        type = (JSSrcNoteType) SN_TYPE(sn);        if (type == SRC_SETLINE) {            lineno = (uintN) js_GetSrcNoteOffset(sn, 0);        } else if (type == SRC_NEWLINE) {            lineno++;        }    }    return 1 + lineno - script->lineno;}

⌨️ 快捷键说明

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