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

📄 jsfun.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=8 sw=4 et tw=78: * * ***** 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 function support. */#include "jsstddef.h"#include <string.h>#include "jstypes.h"#include "jsbit.h"#include "jsutil.h" /* Added by JSIFY */#include "jsapi.h"#include "jsarray.h"#include "jsatom.h"#include "jscntxt.h"#include "jsconfig.h"#include "jsdbgapi.h"#include "jsfun.h"#include "jsgc.h"#include "jsinterp.h"#include "jslock.h"#include "jsnum.h"#include "jsobj.h"#include "jsopcode.h"#include "jsparse.h"#include "jsscan.h"#include "jsscope.h"#include "jsscript.h"#include "jsstr.h"#include "jsexn.h"#if JS_HAS_GENERATORS# include "jsiter.h"#endif/* Generic function/call/arguments tinyids -- also reflected bit numbers. */enum {    CALL_ARGUMENTS  = -1,       /* predefined arguments local variable */    CALL_CALLEE     = -2,       /* reference to active function's object */    ARGS_LENGTH     = -3,       /* number of actual args, arity if inactive */    ARGS_CALLEE     = -4,       /* reference from arguments to active funobj */    FUN_ARITY       = -5,       /* number of formal parameters; desired argc */    FUN_NAME        = -6,       /* function name, "" if anonymous */    FUN_CALLER      = -7        /* Function.prototype.caller, backward compat */};#if JSFRAME_OVERRIDE_BITS < 8# error "not enough override bits in JSStackFrame.flags!"#endif#define TEST_OVERRIDE_BIT(fp, tinyid) \    ((fp)->flags & JS_BIT(JSFRAME_OVERRIDE_SHIFT - ((tinyid) + 1)))#define SET_OVERRIDE_BIT(fp, tinyid) \    ((fp)->flags |= JS_BIT(JSFRAME_OVERRIDE_SHIFT - ((tinyid) + 1)))JSBooljs_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp){    JSObject *argsobj;    if (TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) {        JS_ASSERT(fp->callobj);        return OBJ_GET_PROPERTY(cx, fp->callobj,                                ATOM_TO_JSID(cx->runtime->atomState                                             .argumentsAtom),                                vp);    }    argsobj = js_GetArgsObject(cx, fp);    if (!argsobj)        return JS_FALSE;    *vp = OBJECT_TO_JSVAL(argsobj);    return JS_TRUE;}static JSBoolMarkArgDeleted(JSContext *cx, JSStackFrame *fp, uintN slot){    JSObject *argsobj;    jsval bmapval, bmapint;    size_t nbits, nbytes;    jsbitmap *bitmap;    argsobj = fp->argsobj;    (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval);    nbits = fp->argc;    JS_ASSERT(slot < nbits);    if (JSVAL_IS_VOID(bmapval)) {        if (nbits <= JSVAL_INT_BITS) {            bmapint = 0;            bitmap = (jsbitmap *) &bmapint;        } else {            nbytes = JS_HOWMANY(nbits, JS_BITS_PER_WORD) * sizeof(jsbitmap);            bitmap = (jsbitmap *) JS_malloc(cx, nbytes);            if (!bitmap)                return JS_FALSE;            memset(bitmap, 0, nbytes);            bmapval = PRIVATE_TO_JSVAL(bitmap);            JS_SetReservedSlot(cx, argsobj, 0, bmapval);        }    } else {        if (nbits <= JSVAL_INT_BITS) {            bmapint = JSVAL_TO_INT(bmapval);            bitmap = (jsbitmap *) &bmapint;        } else {            bitmap = (jsbitmap *) JSVAL_TO_PRIVATE(bmapval);        }    }    JS_SET_BIT(bitmap, slot);    if (bitmap == (jsbitmap *) &bmapint) {        bmapval = INT_TO_JSVAL(bmapint);        JS_SetReservedSlot(cx, argsobj, 0, bmapval);    }    return JS_TRUE;}/* NB: Infallible predicate, false does not mean error/exception. */static JSBoolArgWasDeleted(JSContext *cx, JSStackFrame *fp, uintN slot){    JSObject *argsobj;    jsval bmapval, bmapint;    jsbitmap *bitmap;    argsobj = fp->argsobj;    (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval);    if (JSVAL_IS_VOID(bmapval))        return JS_FALSE;    if (fp->argc <= JSVAL_INT_BITS) {        bmapint = JSVAL_TO_INT(bmapval);        bitmap = (jsbitmap *) &bmapint;    } else {        bitmap = (jsbitmap *) JSVAL_TO_PRIVATE(bmapval);    }    return JS_TEST_BIT(bitmap, slot) != 0;}JSBooljs_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id,                   JSObject **objp, jsval *vp){    jsval val;    JSObject *obj;    uintN slot;    if (TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) {        JS_ASSERT(fp->callobj);        if (!OBJ_GET_PROPERTY(cx, fp->callobj,                              ATOM_TO_JSID(cx->runtime->atomState                                           .argumentsAtom),                              &val)) {            return JS_FALSE;        }        if (JSVAL_IS_PRIMITIVE(val)) {            obj = js_ValueToNonNullObject(cx, val);            if (!obj)                return JS_FALSE;        } else {            obj = JSVAL_TO_OBJECT(val);        }        *objp = obj;        return OBJ_GET_PROPERTY(cx, obj, id, vp);    }    *objp = NULL;    *vp = JSVAL_VOID;    if (JSID_IS_INT(id)) {        slot = (uintN) JSID_TO_INT(id);        if (slot < fp->argc) {            if (fp->argsobj && ArgWasDeleted(cx, fp, slot))                return OBJ_GET_PROPERTY(cx, fp->argsobj, id, vp);            *vp = fp->argv[slot];        } else {            /*             * Per ECMA-262 Ed. 3, 10.1.8, last bulleted item, do not share             * storage between the formal parameter and arguments[k] for all             * k >= fp->argc && k < fp->fun->nargs.  For example, in             *             *   function f(x) { x = 42; return arguments[0]; }             *   f();             *             * the call to f should return undefined, not 42.  If fp->argsobj             * is null at this point, as it would be in the example, return             * undefined in *vp.             */            if (fp->argsobj)                return OBJ_GET_PROPERTY(cx, fp->argsobj, id, vp);        }    } else {        if (id == ATOM_TO_JSID(cx->runtime->atomState.lengthAtom)) {            if (fp->argsobj && TEST_OVERRIDE_BIT(fp, ARGS_LENGTH))                return OBJ_GET_PROPERTY(cx, fp->argsobj, id, vp);            *vp = INT_TO_JSVAL((jsint) fp->argc);        }    }    return JS_TRUE;}JSObject *js_GetArgsObject(JSContext *cx, JSStackFrame *fp){    JSObject *argsobj, *global, *parent;    /*     * We must be in a function activation; the function must be lightweight     * or else fp must have a variable object.     */    JS_ASSERT(fp->fun && (!(fp->fun->flags & JSFUN_HEAVYWEIGHT) || fp->varobj));    /* Skip eval and debugger frames. */    while (fp->flags & JSFRAME_SPECIAL)        fp = fp->down;    /* Create an arguments object for fp only if it lacks one. */    argsobj = fp->argsobj;    if (argsobj)        return argsobj;    /* Link the new object to fp so it can get actual argument values. */    argsobj = js_NewObject(cx, &js_ArgumentsClass, NULL, NULL);    if (!argsobj || !JS_SetPrivate(cx, argsobj, fp)) {        cx->weakRoots.newborn[GCX_OBJECT] = NULL;        return NULL;    }    /*     * Give arguments an intrinsic scope chain link to fp's global object.     * Since the arguments object lacks a prototype because js_ArgumentsClass     * is not initialized, js_NewObject won't assign a default parent to it.     *     * Therefore if arguments is used as the head of an eval scope chain (via     * a direct or indirect call to eval(program, arguments)), any reference     * to a standard class object in the program will fail to resolve due to     * js_GetClassPrototype not being able to find a global object containing     * the standard prototype by starting from arguments and following parent.     */    global = fp->scopeChain;    while ((parent = OBJ_GET_PARENT(cx, global)) != NULL)        global = parent;    argsobj->slots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(global);    fp->argsobj = argsobj;    return argsobj;}static JSBoolargs_enumerate(JSContext *cx, JSObject *obj);JSBooljs_PutArgsObject(JSContext *cx, JSStackFrame *fp){    JSObject *argsobj;    jsval bmapval, rval;    JSBool ok;    JSRuntime *rt;    /*     * Reuse args_enumerate here to reflect fp's actual arguments as indexed     * elements of argsobj.  Do this first, before clearing and freeing the     * deleted argument slot bitmap, because args_enumerate depends on that.     */    argsobj = fp->argsobj;    ok = args_enumerate(cx, argsobj);    /*     * Now clear the deleted argument number bitmap slot and free the bitmap,     * if one was actually created due to 'delete arguments[0]' or similar.     */    (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval);    if (!JSVAL_IS_VOID(bmapval)) {        JS_SetReservedSlot(cx, argsobj, 0, JSVAL_VOID);        if (fp->argc > JSVAL_INT_BITS)            JS_free(cx, JSVAL_TO_PRIVATE(bmapval));    }    /*     * Now get the prototype properties so we snapshot fp->fun and fp->argc     * before fp goes away.     */    rt = cx->runtime;    ok &= js_GetProperty(cx, argsobj, ATOM_TO_JSID(rt->atomState.calleeAtom),                         &rval);    ok &= js_SetProperty(cx, argsobj, ATOM_TO_JSID(rt->atomState.calleeAtom),                         &rval);    ok &= js_GetProperty(cx, argsobj, ATOM_TO_JSID(rt->atomState.lengthAtom),                         &rval);    ok &= js_SetProperty(cx, argsobj, ATOM_TO_JSID(rt->atomState.lengthAtom),                         &rval);    /*     * Clear the private pointer to fp, which is about to go away (js_Invoke).     * Do this last because the args_enumerate and js_GetProperty calls above     * need to follow the private slot to find fp.     */    ok &= JS_SetPrivate(cx, argsobj, NULL);    fp->argsobj = NULL;    return ok;}static JSBoolargs_delProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp){    jsint slot;    JSStackFrame *fp;    if (!JSVAL_IS_INT(id))        return JS_TRUE;    fp = (JSStackFrame *)         JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);    if (!fp)        return JS_TRUE;    JS_ASSERT(fp->argsobj);    slot = JSVAL_TO_INT(id);    switch (slot) {      case ARGS_CALLEE:      case ARGS_LENGTH:        SET_OVERRIDE_BIT(fp, slot);        break;      default:        if ((uintN)slot < fp->argc && !MarkArgDeleted(cx, fp, slot))            return JS_FALSE;        break;    }    return JS_TRUE;}static JSBoolargs_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp){    jsint slot;    JSStackFrame *fp;    if (!JSVAL_IS_INT(id))        return JS_TRUE;    fp = (JSStackFrame *)         JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);    if (!fp)        return JS_TRUE;    JS_ASSERT(fp->argsobj);    slot = JSVAL_TO_INT(id);    switch (slot) {      case ARGS_CALLEE:        if (!TEST_OVERRIDE_BIT(fp, slot))            *vp = fp->argv ? fp->argv[-2] : OBJECT_TO_JSVAL(fp->fun->object);        break;      case ARGS_LENGTH:        if (!TEST_OVERRIDE_BIT(fp, slot))            *vp = INT_TO_JSVAL((jsint)fp->argc);        break;      default:        if ((uintN)slot < fp->argc && !ArgWasDeleted(cx, fp, slot))            *vp = fp->argv[slot];        break;    }    return JS_TRUE;}static JSBoolargs_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp){    JSStackFrame *fp;    jsint slot;    if (!JSVAL_IS_INT(id))        return JS_TRUE;    fp = (JSStackFrame *)         JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);    if (!fp)        return JS_TRUE;

⌨️ 快捷键说明

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