Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Functions | Variables
jsscript.h File Reference
#include "jsatom.h"
#include "jsprvtd.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  JSTryNote
struct  JSScript

Defines

#define JSTRYNOTE_GRAIN   sizeof(ptrdiff_t)
#define JSTRYNOTE_ALIGNMASK   (JSTRYNOTE_GRAIN - 1)
#define SCRIPT_NOTES(script)   ((jssrcnote*)((script)->code+(script)->length))
#define SCRIPT_FIND_CATCH_START(script, pc, catchpc)
#define js_GetSrcNote(script, pc)   js_GetSrcNoteCached(cx, script, pc)

Functions

jsbytecodejs_FindFinallyHandler (JSScript *script, jsbytecode *pc)
 JS_FRIEND_DATA (JSClass) js_ScriptClass
JSObjectjs_InitScriptClass (JSContext *cx, JSObject *obj)
JSBool js_InitRuntimeScriptState (JSRuntime *rt)
void js_FinishRuntimeScriptState (JSRuntime *rt)
void js_FreeRuntimeScriptState (JSRuntime *rt)
const char * js_SaveScriptFilename (JSContext *cx, const char *filename)
const char * js_SaveScriptFilenameRT (JSRuntime *rt, const char *filename, uint32 flags)
uint32 js_GetScriptFilenameFlags (const char *filename)
void js_MarkScriptFilename (const char *filename)
void js_MarkScriptFilenames (JSRuntime *rt, JSBool keepAtoms)
void js_SweepScriptFilenames (JSRuntime *rt)
JSScriptjs_NewScript (JSContext *cx, uint32 length, uint32 snlength, uint32 tnlength)
 JS_FRIEND_API (JSScript *) js_NewScriptFromCG(JSContext *cx
 JS_FRIEND_API (void) js_CallNewScriptHook(JSContext *cx
void js_DestroyScript (JSContext *cx, JSScript *script)
void js_MarkScript (JSContext *cx, JSScript *script)
jssrcnotejs_GetSrcNoteCached (JSContext *cx, JSScript *script, jsbytecode *pc)
uintN js_PCToLineNumber (JSContext *cx, JSScript *script, jsbytecode *pc)
jsbytecodejs_LineNumberToPC (JSScript *script, uintN lineno)
 JS_FRIEND_API (uintN) js_GetScriptLineExtent(JSScript *script)
JSBool js_XDRScript (JSXDRState *xdr, JSScript **scriptp, JSBool *magic)

Variables

JSCodeGeneratorcg
JSCodeGenerator JSFunctionfun
JSScriptscript

Class Documentation

struct JSTryNote

Definition at line 58 of file jsscript.h.

Class Members
ptrdiff_t catchStart
ptrdiff_t length
ptrdiff_t start
struct JSScript

Definition at line 67 of file jsscript.h.

Collaboration diagram for JSScript:
Class Members
JSAtomMap atomMap
jsbytecode * code
uintN depth
const char * filename
uint32 length
uintN lineno
jsbytecode * main
uint16 numGlobalVars
JSObject * object
JSPrincipals * principals
JSTryNote * trynotes
uint16 version

Define Documentation

Definition at line 196 of file jsscript.h.

Definition at line 65 of file jsscript.h.

Definition at line 64 of file jsscript.h.

#define SCRIPT_FIND_CATCH_START (   script,
  pc,
  catchpc 
)
Value:
JS_BEGIN_MACRO                                                            \
        JSTryNote *tn_ = (script)->trynotes;                                  \
        jsbytecode *catchpc_ = NULL;                                          \
        if (tn_) {                                                            \
            ptrdiff_t off_ = PTRDIFF(pc, (script)->main, jsbytecode);         \
            if (off_ >= 0) {                                                  \
                while ((jsuword)(off_ - tn_->start) >= (jsuword)tn_->length)  \
                    ++tn_;                                                    \
                if (tn_->catchStart)                                          \
                    catchpc_ = (script)->main + tn_->catchStart;              \
            }                                                                 \
        }                                                                     \
        catchpc = catchpc_;                                                   \
    JS_END_MACRO

Definition at line 85 of file jsscript.h.

Definition at line 83 of file jsscript.h.


Function Documentation

void js_DestroyScript ( JSContext cx,
JSScript script 
)

Definition at line 1456 of file jsscript.c.

{
    js_CallDestroyScriptHook(cx, script);

    JS_ClearScriptTraps(cx, script);
    js_FreeAtomMap(cx, &script->atomMap);
    if (script->principals)
        JSPRINCIPALS_DROP(cx, script->principals);
    if (JS_GSN_CACHE(cx).script == script)
        JS_CLEAR_GSN_CACHE(cx);
    JS_free(cx, script);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1676 of file jsscript.c.

{
    JSTryNote *tn;
    ptrdiff_t off;
    JSOp op2;

    tn = script->trynotes;
    if (!tn)
        return NULL;

    off = pc - script->main;
    if (off < 0)
        return NULL;

    JS_ASSERT(tn->catchStart != 0);
    do {
        if ((jsuword)(off - tn->start) < (jsuword)tn->length) {
            /*
             * We have a handler: is it the finally one, or a catch handler?
             *
             * Catch bytecode begins with:   JSOP_SETSP JSOP_ENTERBLOCK
             * Finally bytecode begins with: JSOP_SETSP JSOP_(GOSUB|EXCEPTION)
             */
            pc = script->main + tn->catchStart;
            JS_ASSERT(*pc == JSOP_SETSP);
            op2 = pc[JSOP_SETSP_LENGTH];
            if (op2 != JSOP_ENTERBLOCK) {
                JS_ASSERT(op2 == JSOP_GOSUB || op2 == JSOP_EXCEPTION);
                return pc;
            }
        }
    } while ((++tn)->catchStart != 0);
    return NULL;
}

Here is the caller graph for this function:

Definition at line 1084 of file jsscript.c.

{
    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
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1099 of file jsscript.c.

Here is the call graph for this function:

Here is the caller graph for this function:

uint32 js_GetScriptFilenameFlags ( const char *  filename)

Definition at line 1261 of file jsscript.c.

{
    ScriptFilenameEntry *sfe;

    sfe = FILENAME_TO_SFE(filename);
    ASSERT_VALID_SFE(sfe);
    return sfe->flags;
}

Here is the caller graph for this function:

jssrcnote* js_GetSrcNoteCached ( JSContext cx,
JSScript script,
jsbytecode pc 
)

Definition at line 1495 of file jsscript.c.

{
    ptrdiff_t target, offset;
    GSNCacheEntry *entry;
    jssrcnote *sn, *result;
    uintN nsrcnotes;


    target = PTRDIFF(pc, script->code, jsbytecode);
    if ((uint32)target >= script->length)
        return NULL;

    if (JS_GSN_CACHE(cx).script == script) {
        JS_METER_GSN_CACHE(cx, hits);
        entry = (GSNCacheEntry *)
                JS_DHashTableOperate(&JS_GSN_CACHE(cx).table, pc,
                                     JS_DHASH_LOOKUP);
        return entry->sn;
    }

    JS_METER_GSN_CACHE(cx, misses);
    offset = 0;
    for (sn = SCRIPT_NOTES(script); ; sn = SN_NEXT(sn)) {
        if (SN_IS_TERMINATOR(sn)) {
            result = NULL;
            break;
        }
        offset += SN_DELTA(sn);
        if (offset == target && SN_IS_GETTABLE(sn)) {
            result = sn;
            break;
        }
    }

    if (JS_GSN_CACHE(cx).script != script &&
        script->length >= GSN_CACHE_THRESHOLD) {
        JS_CLEAR_GSN_CACHE(cx);
        nsrcnotes = 0;
        for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn);
             sn = SN_NEXT(sn)) {
            if (SN_IS_GETTABLE(sn))
                ++nsrcnotes;
        }
        if (!JS_DHashTableInit(&JS_GSN_CACHE(cx).table, JS_DHashGetStubOps(),
                               NULL, sizeof(GSNCacheEntry), nsrcnotes)) {
            JS_GSN_CACHE(cx).table.ops = NULL;
        } else {
            pc = script->code;
            for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn);
                 sn = SN_NEXT(sn)) {
                pc += SN_DELTA(sn);
                if (SN_IS_GETTABLE(sn)) {
                    entry = (GSNCacheEntry *)
                            JS_DHashTableOperate(&JS_GSN_CACHE(cx).table, pc,
                                                 JS_DHASH_ADD);
                    entry->pc = pc;
                    entry->sn = sn;
                }
            }
            JS_GSN_CACHE(cx).script = script;
            JS_METER_GSN_CACHE(cx, fills);
        }
    }

    return result;
}

Here is the call graph for this function:

Definition at line 1056 of file jsscript.c.

{
#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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1000 of file jsscript.c.

{
    return JS_InitClass(cx, obj, NULL, &js_ScriptClass, Script, 1,
                        NULL, script_methods, NULL, script_static_methods);
}

Here is the call graph for this function:

Here is the caller graph for this function:

jsbytecode* js_LineNumberToPC ( JSScript script,
uintN  lineno 
)

Definition at line 1619 of file jsscript.c.

{
    ptrdiff_t offset, best;
    uintN lineno, bestdiff, diff;
    jssrcnote *sn;
    JSSrcNoteType type;

    offset = 0;
    best = -1;
    lineno = script->lineno;
    bestdiff = SN_LINE_LIMIT;
    for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
        if (lineno == target)
            goto out;
        if (lineno > target) {
            diff = lineno - target;
            if (diff < bestdiff) {
                bestdiff = diff;
                best = offset;
            }
        }
        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++;
        }
    }
    if (best >= 0)
        offset = best;
out:
    return script->code + offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void js_MarkScript ( JSContext cx,
JSScript script 
)

Definition at line 1470 of file jsscript.c.

{
    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]);

    if (script->filename)
        js_MarkScriptFilename(script->filename);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void js_MarkScriptFilename ( const char *  filename)

Definition at line 1271 of file jsscript.c.

Here is the caller graph for this function:

void js_MarkScriptFilenames ( JSRuntime rt,
JSBool  keepAtoms 
)

Definition at line 1290 of file jsscript.c.

{
    JSCList *head, *link;
    ScriptFilenamePrefix *sfp;

    if (!rt->scriptFilenameTable)
        return;

    if (keepAtoms) {
        JS_HashTableEnumerateEntries(rt->scriptFilenameTable,
                                     js_script_filename_marker,
                                     rt);
    }
    for (head = &rt->scriptFilenamePrefixes, link = head->next;
         link != head;
         link = link->next) {
        sfp = (ScriptFilenamePrefix *) link;
        js_MarkScriptFilename(sfp->name);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

JSScript* js_NewScript ( JSContext cx,
uint32  length,
uint32  snlength,
uint32  tnlength 
)

Definition at line 1339 of file jsscript.c.

{
    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);
        memset(script->trynotes, 0, ntrynotes * sizeof(JSTryNote));
    }
    return script;
}

Here is the call graph for this function:

Here is the caller graph for this function:

uintN js_PCToLineNumber ( JSContext cx,
JSScript script,
jsbytecode pc 
)

Definition at line 1563 of file jsscript.c.

{
    JSAtom *atom;
    JSFunction *fun;
    uintN lineno;
    ptrdiff_t offset, target;
    jssrcnote *sn;
    JSSrcNoteType type;

    /* Cope with JSStackFrame.pc value prior to entering js_Interpret. */
    if (!pc)
        return 0;

    /*
     * Special case: function definition needs no line number note because
     * the function's script contains its starting line number.
     */
    if (*pc == JSOP_DEFFUN ||
        (*pc == JSOP_LITOPX && pc[1 + LITERAL_INDEX_LEN] == JSOP_DEFFUN)) {
        atom = js_GetAtom(cx, &script->atomMap,
                          (*pc == JSOP_DEFFUN)
                          ? GET_ATOM_INDEX(pc)
                          : GET_LITERAL_INDEX(pc));
        fun = (JSFunction *) JS_GetPrivate(cx, ATOM_TO_OBJECT(atom));
        JS_ASSERT(FUN_INTERPRETED(fun));
        return fun->u.i.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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* js_SaveScriptFilename ( JSContext cx,
const char *  filename 
)

Definition at line 1194 of file jsscript.c.

{
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* js_SaveScriptFilenameRT ( JSRuntime rt,
const char *  filename,
uint32  flags 
)

Definition at line 1229 of file jsscript.c.

{
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1323 of file jsscript.c.

{
    if (!rt->scriptFilenameTable)
        return;

    JS_HashTableEnumerateEntries(rt->scriptFilenameTable,
                                 js_script_filename_sweeper,
                                 rt);
#ifdef DEBUG_notme
#ifdef DEBUG_SFTBL
    printf("script filename table savings so far: %u\n", sftbl_savings);
#endif
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

JSBool js_XDRScript ( JSXDRState xdr,
JSScript **  scriptp,
JSBool magic 
)

Definition at line 452 of file jsscript.c.

{
    JSContext *cx;
    JSScript *script, *newscript, *oldscript;
    uint32 length, lineno, depth, magic, nsrcnotes, ntrynotes;
    uint32 prologLength, version;
    JSBool filenameWasSaved;
    jssrcnote *notes, *sn;

    cx = xdr->cx;
    script = *scriptp;
    nsrcnotes = ntrynotes = 0;
    filenameWasSaved = JS_FALSE;
    notes = NULL;

    /*
     * Encode prologLength and version after script->length (_2 or greater),
     * but decode both new (>= _2) and old, prolog&version-free (_1) scripts.
     * Version _3 supports principals serialization.  Version _4 reorders the
     * nsrcnotes and ntrynotes fields to come before everything except magic,
     * length, prologLength, and version, so that srcnote and trynote storage
     * can be allocated as part of the JSScript (along with bytecode storage).
     *
     * So far, the magic number has not changed for every jsopcode.tbl change.
     * We stipulate forward compatibility by requiring old bytecodes never to
     * change or go away (modulo a few exceptions before the XDR interfaces
     * evolved, and a few exceptions during active trunk development).  With
     * the addition of JSOP_STOP to support JS_THREADED_INTERP, we make a new
     * magic number (_5) so that we know to append JSOP_STOP to old scripts
     * when deserializing.
     */
    if (xdr->mode == JSXDR_ENCODE)
        magic = JSXDR_MAGIC_SCRIPT_CURRENT;
    if (!JS_XDRUint32(xdr, &magic))
        return JS_FALSE;
    JS_ASSERT((uint32)JSXDR_MAGIC_SCRIPT_5 - (uint32)JSXDR_MAGIC_SCRIPT_1 == 4);
    if (magic - (uint32)JSXDR_MAGIC_SCRIPT_1 > 4) {
        if (!hasMagic) {
            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                                 JSMSG_BAD_SCRIPT_MAGIC);
            return JS_FALSE;
        }
        *hasMagic = JS_FALSE;
        return JS_TRUE;
    }
    if (hasMagic)
        *hasMagic = JS_TRUE;

    if (xdr->mode == JSXDR_ENCODE) {
        length = script->length;
        prologLength = PTRDIFF(script->main, script->code, jsbytecode);
        JS_ASSERT((int16)script->version != JSVERSION_UNKNOWN);
        version = (uint32)script->version | (script->numGlobalVars << 16);
        lineno = (uint32)script->lineno;
        depth = (uint32)script->depth;

        /* Count the srcnotes, keeping notes pointing at the first one. */
        notes = SCRIPT_NOTES(script);
        for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn))
            continue;
        nsrcnotes = PTRDIFF(sn, notes, jssrcnote);
        nsrcnotes++;            /* room for the terminator */

        /* Count the trynotes. */
        if (script->trynotes) {
            while (script->trynotes[ntrynotes].catchStart)
                ntrynotes++;
            ntrynotes++;        /* room for the end marker */
        }
    }

    if (!JS_XDRUint32(xdr, &length))
        return JS_FALSE;
    if (magic >= JSXDR_MAGIC_SCRIPT_2) {
        if (!JS_XDRUint32(xdr, &prologLength))
            return JS_FALSE;
        if (!JS_XDRUint32(xdr, &version))
            return JS_FALSE;

        /* To fuse allocations, we need srcnote and trynote counts early. */
        if (magic >= JSXDR_MAGIC_SCRIPT_4) {
            if (!JS_XDRUint32(xdr, &nsrcnotes))
                return JS_FALSE;
            if (!JS_XDRUint32(xdr, &ntrynotes))
                return JS_FALSE;
        }
    }

    if (xdr->mode == JSXDR_DECODE) {
        size_t alloclength = length;
        if (magic < JSXDR_MAGIC_SCRIPT_5)
            ++alloclength;      /* add a byte for JSOP_STOP */

        script = js_NewScript(cx, alloclength, nsrcnotes, ntrynotes);
        if (!script)
            return JS_FALSE;
        if (magic >= JSXDR_MAGIC_SCRIPT_2) {
            script->main += prologLength;
            script->version = (JSVersion) (version & 0xffff);
            script->numGlobalVars = (uint16) (version >> 16);

            /* If we know nsrcnotes, we allocated space for notes in script. */
            if (magic >= JSXDR_MAGIC_SCRIPT_4)
                notes = SCRIPT_NOTES(script);
        }
        *scriptp = script;
    }

    /*
     * Control hereafter must goto error on failure, in order for the DECODE
     * case to destroy script and conditionally free notes, which if non-null
     * in the (DECODE and magic < _4) case must point at a temporary vector
     * allocated just below.
     */
    oldscript = xdr->script;
    xdr->script = script;
    if (!JS_XDRBytes(xdr, (char *)script->code, length * sizeof(jsbytecode)) ||
        !XDRAtomMap(xdr, &script->atomMap)) {
        goto error;
    }

    if (magic < JSXDR_MAGIC_SCRIPT_5) {
        if (xdr->mode == JSXDR_DECODE) {
            /*
             * Append JSOP_STOP to old scripts, to relieve the interpreter
             * from having to bounds-check pc.  Also take care to increment
             * length, as it is used below and must count all bytecode.
             */
            script->code[length++] = JSOP_STOP;
        }

        if (magic < JSXDR_MAGIC_SCRIPT_4) {
            if (!JS_XDRUint32(xdr, &nsrcnotes))
                goto error;
            if (xdr->mode == JSXDR_DECODE) {
                notes = (jssrcnote *)
                        JS_malloc(cx, nsrcnotes * sizeof(jssrcnote));
                if (!notes)
                    goto error;
            }
        }
    }

    if (!JS_XDRBytes(xdr, (char *)notes, nsrcnotes * sizeof(jssrcnote)) ||
        !JS_XDRCStringOrNull(xdr, (char **)&script->filename) ||
        !JS_XDRUint32(xdr, &lineno) ||
        !JS_XDRUint32(xdr, &depth) ||
        (magic < JSXDR_MAGIC_SCRIPT_4 && !JS_XDRUint32(xdr, &ntrynotes))) {
        goto error;
    }

    /* Script principals transcoding support comes with versions >= _3. */
    if (magic >= JSXDR_MAGIC_SCRIPT_3) {
        JSPrincipals *principals;
        uint32 encodeable;

        if (xdr->mode == JSXDR_ENCODE) {
            principals = script->principals;
            encodeable = (cx->runtime->principalsTranscoder != NULL);
            if (!JS_XDRUint32(xdr, &encodeable))
                goto error;
            if (encodeable &&
                !cx->runtime->principalsTranscoder(xdr, &principals)) {
                goto error;
            }
        } else {
            if (!JS_XDRUint32(xdr, &encodeable))
                goto error;
            if (encodeable) {
                if (!cx->runtime->principalsTranscoder) {
                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                                         JSMSG_CANT_DECODE_PRINCIPALS);
                    goto error;
                }
                if (!cx->runtime->principalsTranscoder(xdr, &principals))
                    goto error;
                script->principals = principals;
            }
        }
    }

    if (xdr->mode == JSXDR_DECODE) {
        const char *filename = script->filename;
        if (filename) {
            filename = js_SaveScriptFilename(cx, filename);
            if (!filename)
                goto error;
            JS_free(cx, (void *) script->filename);
            script->filename = filename;
            filenameWasSaved = JS_TRUE;
        }
        script->lineno = (uintN)lineno;
        script->depth = (uintN)depth;

        if (magic < JSXDR_MAGIC_SCRIPT_4) {
            /*
             * Argh, we have to reallocate script, copy notes into the extra
             * space after the bytecodes, and free the temporary notes vector.
             * First, add enough slop to nsrcnotes so we can align the address
             * after the srcnotes of the first trynote.
             */
            uint32 osrcnotes = nsrcnotes;

            if (ntrynotes)
                nsrcnotes += JSTRYNOTE_ALIGNMASK;
            newscript = (JSScript *) JS_realloc(cx, script,
                                                sizeof(JSScript) +
                                                length * sizeof(jsbytecode) +
                                                nsrcnotes * sizeof(jssrcnote) +
                                                ntrynotes * sizeof(JSTryNote));
            if (!newscript)
                goto error;

            *scriptp = script = newscript;
            script->code = (jsbytecode *)(script + 1);
            script->main = script->code + prologLength;
            memcpy(script->code + length, notes, osrcnotes * sizeof(jssrcnote));
            JS_free(cx, (void *) notes);
            notes = NULL;
            if (ntrynotes) {
                script->trynotes = (JSTryNote *)
                                   ((jsword)(SCRIPT_NOTES(script) + nsrcnotes) &
                                    ~(jsword)JSTRYNOTE_ALIGNMASK);
                memset(script->trynotes, 0, ntrynotes * sizeof(JSTryNote));
            }
        }
    }

    while (ntrynotes) {
        JSTryNote *tn = &script->trynotes[--ntrynotes];
        uint32 start = (uint32) tn->start,
               catchLength = (uint32) tn->length,
               catchStart = (uint32) tn->catchStart;

        if (!JS_XDRUint32(xdr, &start) ||
            !JS_XDRUint32(xdr, &catchLength) ||
            !JS_XDRUint32(xdr, &catchStart)) {
            goto error;
        }
        tn->start = (ptrdiff_t) start;
        tn->length = (ptrdiff_t) catchLength;
        tn->catchStart = (ptrdiff_t) catchStart;
    }

    xdr->script = oldscript;
    return JS_TRUE;

  error:
    if (xdr->mode == JSXDR_DECODE) {
        if (script->filename && !filenameWasSaved) {
            JS_free(cx, (void *) script->filename);
            script->filename = NULL;
        }
        if (notes && magic < JSXDR_MAGIC_SCRIPT_4)
            JS_free(cx, (void *) notes);
        js_DestroyScript(cx, script);
        *scriptp = NULL;
    }
    return JS_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 171 of file jsscript.h.

Definition at line 171 of file jsscript.h.

Definition at line 180 of file jsscript.h.