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

📄 jsscript.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- 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 script operations. */#include "jsstddef.h"#include <string.h>#include "jstypes.h"#include "jsutil.h" /* Added by JSIFY */#include "jsprf.h"#include "jsapi.h"#include "jsatom.h"#include "jscntxt.h"#include "jsconfig.h"#include "jsdbgapi.h"#include "jsemit.h"#include "jsfun.h"#include "jsinterp.h"#include "jslock.h"#include "jsnum.h"#include "jsopcode.h"#include "jsscript.h"#if JS_HAS_XDR#include "jsxdrapi.h"#endif#if JS_HAS_SCRIPT_OBJECT#if JS_HAS_TOSOURCEstatic JSBoolscript_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,                jsval *rval){    JSScript *script;    size_t i, j, k, n;    char buf[16];    jschar *s, *t;    uint32 indent;    JSString *str;    if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))        return JS_FALSE;    script = (JSScript *) JS_GetPrivate(cx, obj);    /* Let n count the source string length, j the "front porch" length. */    j = JS_snprintf(buf, sizeof buf, "(new %s(", js_ScriptClass.name);    n = j + 2;    if (!script) {        /* Let k count the constructor argument string length. */        k = 0;        s = NULL;               /* quell GCC overwarning */    } else {        indent = 0;        if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent))            return JS_FALSE;        str = JS_DecompileScript(cx, script, "Script.prototype.toSource",                                 (uintN)indent);        if (!str)            return JS_FALSE;        str = js_QuoteString(cx, str, '\'');        if (!str)            return JS_FALSE;        s = JSSTRING_CHARS(str);        k = JSSTRING_LENGTH(str);        n += k;    }    /* Allocate the source string and copy into it. */    t = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar));    if (!t)        return JS_FALSE;    for (i = 0; i < j; i++)        t[i] = buf[i];    for (j = 0; j < k; i++, j++)        t[i] = s[j];    t[i++] = ')';    t[i++] = ')';    t[i] = 0;    /* Create and return a JS string for t. */    str = JS_NewUCString(cx, t, n);    if (!str) {        JS_free(cx, t);        return JS_FALSE;    }    *rval = STRING_TO_JSVAL(str);    return JS_TRUE;}#endif /* JS_HAS_TOSOURCE */static JSBoolscript_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,                jsval *rval){    JSScript *script;    uint32 indent;    JSString *str;    if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))        return JS_FALSE;    script = (JSScript *) JS_GetPrivate(cx, obj);    if (!script) {        *rval = STRING_TO_JSVAL(cx->runtime->emptyString);        return JS_TRUE;    }    indent = 0;    if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent))        return JS_FALSE;    str = JS_DecompileScript(cx, script, "Script.prototype.toString",                             (uintN)indent);    if (!str)        return JS_FALSE;    *rval = STRING_TO_JSVAL(str);    return JS_TRUE;}static JSBoolscript_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,               jsval *rval){    JSScript *oldscript, *script;    JSString *str;    JSStackFrame *fp, *caller;    JSObject *scopeobj;    const char *file;    uintN line;    JSPrincipals *principals;    /* Make sure obj is a Script object. */    if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))        return JS_FALSE;    /* If no args, leave private undefined and return early. */    if (argc == 0)        goto out;    /* Otherwise, the first arg is the script source to compile. */    str = js_ValueToString(cx, argv[0]);    if (!str)        return JS_FALSE;    /* Compile using the caller's scope chain, which js_Invoke passes to fp. */    fp = cx->fp;    caller = JS_GetScriptedCaller(cx, fp);    JS_ASSERT(!caller || fp->scopeChain == caller->scopeChain);    scopeobj = NULL;    if (argc >= 2) {        if (!js_ValueToObject(cx, argv[1], &scopeobj))            return JS_FALSE;        argv[1] = OBJECT_TO_JSVAL(scopeobj);    }    if (caller) {        if (!scopeobj)            scopeobj = caller->scopeChain;        file = caller->script->filename;        line = js_PCToLineNumber(cx, caller->script, caller->pc);        principals = JS_EvalFramePrincipals(cx, fp, caller);    } else {        file = NULL;        line = 0;        principals = NULL;    }    /* Compile the new script using the caller's scope chain, a la eval(). */    fp->flags |= JSFRAME_EVAL;    script = JS_CompileUCScriptForPrincipals(cx, scopeobj, principals,                                             JSSTRING_CHARS(str),                                             JSSTRING_LENGTH(str),                                             file, line);    if (!script)        return JS_FALSE;    /* Swap script for obj's old script, if any. */    oldscript = (JSScript *) JS_GetPrivate(cx, obj);    if (!JS_SetPrivate(cx, obj, script)) {        js_DestroyScript(cx, script);        return JS_FALSE;    }    if (oldscript)        js_DestroyScript(cx, oldscript);    script->object = obj;out:    /* Return the object. */    *rval = OBJECT_TO_JSVAL(obj);    return JS_TRUE;}static JSBoolscript_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    JSScript *script;    JSObject *scopeobj, *parent;    JSStackFrame *fp, *caller;    if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))        return JS_FALSE;    script = (JSScript *) JS_GetPrivate(cx, obj);    if (!script)        return JS_TRUE;    scopeobj = NULL;    if (argc) {        if (!js_ValueToObject(cx, argv[0], &scopeobj))            return JS_FALSE;        argv[0] = OBJECT_TO_JSVAL(scopeobj);    }    /*     * Emulate eval() by using caller's this, var object, sharp array, etc.,     * all propagated by js_Execute via a non-null fourth (down) argument to     * js_Execute.  If there is no scripted caller, js_Execute uses its second     * (chain) argument to set the exec frame's varobj, thisp, and scopeChain.     *     * Unlike eval, which the compiler detects, Script.prototype.exec may be     * called from a lightweight function, or even from native code (in which     * case fp->varobj and fp->scopeChain are null).  If exec is called from     * a lightweight function, we will need to get a Call object representing     * its frame, to act as the var object and scope chain head.     */    fp = cx->fp;    caller = JS_GetScriptedCaller(cx, fp);    if (caller && !caller->varobj) {        /* Called from a lightweight function. */        JS_ASSERT(caller->fun && !(caller->fun->flags & JSFUN_HEAVYWEIGHT));        /* Scope chain links from Call object to callee's parent. */        parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(caller->argv[-2]));        if (!js_GetCallObject(cx, caller, parent))            return JS_FALSE;    }    if (!scopeobj) {        /* No scope object passed in: try to use the caller's scope chain. */        if (caller) {            /*             * Load caller->scopeChain after the conditional js_GetCallObject             * call above, which resets scopeChain as well as varobj.             */            scopeobj = caller->scopeChain;        } else {            /*             * Called from native code, so we don't know what scope object to             * use.  We could use parent (see above), but Script.prototype.exec             * might be a shared/sealed "superglobal" method.  A more general             * approach would use cx->globalObject, which will be the same as             * exec.__parent__ in the non-superglobal case.  In the superglobal             * case it's the right object: the global, not the superglobal.             */            scopeobj = cx->globalObject;        }    }    return js_Execute(cx, scopeobj, script, caller, JSFRAME_EVAL, rval);}#if JS_HAS_XDRstatic JSBoolXDRAtomListElement(JSXDRState *xdr, JSAtomListElement *ale){    jsval value;    jsatomid index;    if (xdr->mode == JSXDR_ENCODE)        value = ATOM_KEY(ALE_ATOM(ale));    index = ALE_INDEX(ale);    if (!JS_XDRUint32(xdr, &index))        return JS_FALSE;    ALE_SET_INDEX(ale, index);    if (!JS_XDRValue(xdr, &value))        return JS_FALSE;    if (xdr->mode == JSXDR_DECODE) {        if (!ALE_SET_ATOM(ale, js_AtomizeValue(xdr->cx, value, 0)))            return JS_FALSE;    }    return JS_TRUE;}static JSBoolXDRAtomMap(JSXDRState *xdr, JSAtomMap *map){    uint32 length;    uintN i;    JSBool ok;    if (xdr->mode == JSXDR_ENCODE)        length = map->length;    if (!JS_XDRUint32(xdr, &length))        return JS_FALSE;    if (xdr->mode == JSXDR_DECODE) {        JSContext *cx;        void *mark;        JSAtomList al;        JSAtomListElement *ale;        cx = xdr->cx;        mark = JS_ARENA_MARK(&cx->tempPool);        ATOM_LIST_INIT(&al);        for (i = 0; i < length; i++) {            JS_ARENA_ALLOCATE_TYPE(ale, JSAtomListElement, &cx->tempPool);            if (!ale ||                !XDRAtomListElement(xdr, ale)) {                if (!ale)                    JS_ReportOutOfMemory(cx);                JS_ARENA_RELEASE(&cx->tempPool, mark);                return JS_FALSE;            }            ALE_SET_NEXT(ale, al.list);            al.count++;            al.list = ale;        }        ok = js_InitAtomMap(cx, map, &al);        JS_ARENA_RELEASE(&cx->tempPool, mark);        return ok;    }    if (xdr->mode == JSXDR_ENCODE) {        JSAtomListElement ale;        for (i = 0; i < map->length; i++) {            ALE_SET_ATOM(&ale, map->vector[i]);            ALE_SET_INDEX(&ale, i);            if (!XDRAtomListElement(xdr, &ale))                return JS_FALSE;        }    }    return JS_TRUE;}JSBooljs_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic){    JSContext *cx;    JSScript *script, *newscript;    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).     */    if (xdr->mode == JSXDR_ENCODE)        magic = JSXDR_MAGIC_SCRIPT_CURRENT;    if (!JS_XDRUint32(xdr, &magic))        return JS_FALSE;    if (magic != JSXDR_MAGIC_SCRIPT_4 &&        magic != JSXDR_MAGIC_SCRIPT_3 &&        magic != JSXDR_MAGIC_SCRIPT_2 &&        magic != JSXDR_MAGIC_SCRIPT_1) {        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);        version = (int32)script->version;        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);

⌨️ 快捷键说明

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