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

📄 jsfun.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
        /*         * If we found the property in a different object, don't try sticking         * it into wrong slots vector. This can occur because we have a mutable         * __proto__ slot, and cloned function objects rely on their __proto__         * to delegate to the object that contains the var and arg properties.         */        if (!prop || pobj != obj) {            if (prop)                OBJ_DROP_PROPERTY(cx, pobj, prop);            continue;        }        cprop = (JSScopeProperty *)prop;        LOCKED_OBJ_SET_SLOT(obj, cprop->slot, vec[(uint16) sprop->shortid]);        OBJ_DROP_PROPERTY(cx, obj, prop);    }    return JS_TRUE;}static JSBoolcall_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,             JSObject **objp){    JSStackFrame *fp;    JSObject *funobj;    JSString *str;    JSAtom *atom;    JSObject *obj2;    JSProperty *prop;    JSScopeProperty *sprop;    JSPropertyOp getter, setter;    uintN attrs, slot, nslots, spflags;    jsval *vp, value;    intN shortid;    fp = (JSStackFrame *) JS_GetPrivate(cx, obj);    if (!fp)        return JS_TRUE;    JS_ASSERT(fp->fun);    if (!JSVAL_IS_STRING(id))        return JS_TRUE;    funobj = fp->argv ? JSVAL_TO_OBJECT(fp->argv[-2]) : fp->fun->object;    if (!funobj)        return JS_TRUE;    JS_ASSERT((JSFunction *) JS_GetPrivate(cx, funobj) == fp->fun);    str = JSVAL_TO_STRING(id);    atom = js_AtomizeString(cx, str, 0);    if (!atom)        return JS_FALSE;    if (!js_LookupHiddenProperty(cx, funobj, ATOM_TO_JSID(atom), &obj2, &prop))        return JS_FALSE;    if (prop) {        if (!OBJ_IS_NATIVE(obj2)) {            OBJ_DROP_PROPERTY(cx, obj2, prop);            return JS_TRUE;        }        sprop = (JSScopeProperty *) prop;        getter = sprop->getter;        attrs = sprop->attrs & ~JSPROP_SHARED;        slot = (uintN) sprop->shortid;        OBJ_DROP_PROPERTY(cx, obj2, prop);        /* Ensure we found an arg or var property for the same function. */        if ((sprop->flags & SPROP_IS_HIDDEN) &&            (obj2 == funobj ||             (JSFunction *) JS_GetPrivate(cx, obj2) == fp->fun)) {            if (getter == js_GetArgument) {                vp = fp->argv;                nslots = JS_MAX(fp->argc, fp->fun->nargs);                getter = setter = NULL;            } else {                JS_ASSERT(getter == js_GetLocalVariable);                vp = fp->vars;                nslots = fp->nvars;                getter = js_GetCallVariable;                setter = js_SetCallVariable;            }            if (slot < nslots) {                value = vp[slot];                spflags = SPROP_HAS_SHORTID;                shortid = (intN) slot;            } else {                value = JSVAL_VOID;                spflags = 0;                shortid = 0;            }            if (!js_DefineNativeProperty(cx, obj, ATOM_TO_JSID(atom), value,                                         getter, setter, attrs,                                         spflags, shortid, NULL)) {                return JS_FALSE;            }            *objp = obj;        }    }    return JS_TRUE;}static JSBoolcall_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp){    JSStackFrame *fp;    if (type == JSTYPE_FUNCTION) {        fp = (JSStackFrame *) JS_GetPrivate(cx, obj);        if (fp) {            JS_ASSERT(fp->fun);            *vp = fp->argv ? fp->argv[-2] : OBJECT_TO_JSVAL(fp->fun->object);        }    }    return JS_TRUE;}JSClass js_CallClass = {    js_Call_str,    JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_IS_ANONYMOUS |    JSCLASS_HAS_CACHED_PROTO(JSProto_Call),    JS_PropertyStub,    JS_PropertyStub,    call_getProperty,   call_setProperty,    call_enumerate,     (JSResolveOp)call_resolve,    call_convert,       JS_FinalizeStub,    NULL,               NULL,    NULL,               NULL,    NULL,               NULL,    args_or_call_mark,  NULL,};/* * ECMA-262 specifies that length is a property of function object instances, * but we can avoid that space cost by delegating to a prototype property that * is JSPROP_PERMANENT and JSPROP_SHARED.  Each fun_getProperty call computes * a fresh length value based on the arity of the individual function object's * private data. * * The extensions below other than length, i.e., the ones not in ECMA-262, * are neither JSPROP_READONLY nor JSPROP_SHARED, because for compatibility * with ECMA we must allow a delegating object to override them. */#define LENGTH_PROP_ATTRS (JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED)static JSPropertySpec function_props[] = {    {js_arguments_str, CALL_ARGUMENTS, JSPROP_PERMANENT,  0,0},    {js_arity_str,     FUN_ARITY,      JSPROP_PERMANENT,  0,0},    {js_caller_str,    FUN_CALLER,     JSPROP_PERMANENT,  0,0},    {js_length_str,    ARGS_LENGTH,    LENGTH_PROP_ATTRS, 0,0},    {js_name_str,      FUN_NAME,       JSPROP_PERMANENT,  0,0},    {0,0,0,0,0}};static JSBoolfun_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp){    jsint slot;    JSFunction *fun;    JSStackFrame *fp;    if (!JSVAL_IS_INT(id))        return JS_TRUE;    slot = JSVAL_TO_INT(id);    /*     * Loop because getter and setter can be delegated from another class,     * but loop only for ARGS_LENGTH because we must pretend that f.length     * is in each function instance f, per ECMA-262, instead of only in the     * Function.prototype object (we use JSPROP_PERMANENT with JSPROP_SHARED     * to make it appear so).     *     * This code couples tightly to the attributes for the function_props[]     * initializers above, and to js_SetProperty and js_HasOwnPropertyHelper.     *     * It's important to allow delegating objects, even though they inherit     * this getter (fun_getProperty), to override arguments, arity, caller,     * and name.  If we didn't return early for slot != ARGS_LENGTH, we would     * clobber *vp with the native property value, instead of letting script     * override that value in delegating objects.     *     * Note how that clobbering is what simulates JSPROP_READONLY for all of     * the non-standard properties when the directly addressed object (obj)     * is a function object (i.e., when this loop does not iterate).     */    while (!(fun = (JSFunction *)                   JS_GetInstancePrivate(cx, obj, &js_FunctionClass, NULL))) {        if (slot != ARGS_LENGTH)            return JS_TRUE;        obj = OBJ_GET_PROTO(cx, obj);        if (!obj)            return JS_TRUE;    }    /* Find fun's top-most activation record. */    for (fp = cx->fp; fp && (fp->fun != fun || (fp->flags & JSFRAME_SPECIAL));         fp = fp->down) {        continue;    }    switch (slot) {      case CALL_ARGUMENTS:        /* Warn if strict about f.arguments or equivalent unqualified uses. */        if (!JS_ReportErrorFlagsAndNumber(cx,                                          JSREPORT_WARNING | JSREPORT_STRICT,                                          js_GetErrorMessage, NULL,                                          JSMSG_DEPRECATED_USAGE,                                          js_arguments_str)) {            return JS_FALSE;        }        if (fp) {            if (!js_GetArgsValue(cx, fp, vp))                return JS_FALSE;        } else {            *vp = JSVAL_NULL;        }        break;      case ARGS_LENGTH:      case FUN_ARITY:            *vp = INT_TO_JSVAL((jsint)fun->nargs);        break;      case FUN_NAME:        *vp = fun->atom              ? ATOM_KEY(fun->atom)              : STRING_TO_JSVAL(cx->runtime->emptyString);        break;      case FUN_CALLER:        while (fp && (fp->flags & JSFRAME_SKIP_CALLER) && fp->down)            fp = fp->down;        if (fp && fp->down && fp->down->fun && fp->down->argv)            *vp = fp->down->argv[-2];        else            *vp = JSVAL_NULL;        if (!JSVAL_IS_PRIMITIVE(*vp) && cx->runtime->checkObjectAccess) {            id = ATOM_KEY(cx->runtime->atomState.callerAtom);            if (!cx->runtime->checkObjectAccess(cx, obj, id, JSACC_READ, vp))                return JS_FALSE;        }        break;      default:        /* XXX fun[0] and fun.arguments[0] are equivalent. */        if (fp && fp->fun && (uintN)slot < fp->fun->nargs)            *vp = fp->argv[slot];        break;    }    return JS_TRUE;}static JSBoolfun_enumerate(JSContext *cx, JSObject *obj){    jsid prototypeId;    JSObject *pobj;    JSProperty *prop;    prototypeId = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);    if (!OBJ_LOOKUP_PROPERTY(cx, obj, prototypeId, &pobj, &prop))        return JS_FALSE;    if (prop)        OBJ_DROP_PROPERTY(cx, pobj, prop);    return JS_TRUE;}static JSBoolfun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,            JSObject **objp){    JSFunction *fun;    JSString *str;    JSAtom *prototypeAtom;    /*     * No need to reflect fun.prototype in 'fun.prototype = ...' or in an     * unqualified reference to prototype, which the emitter looks up as a     * hidden atom when attempting to bind to a formal parameter or local     * variable slot.     */    if (flags & (JSRESOLVE_ASSIGNING | JSRESOLVE_HIDDEN))        return JS_TRUE;    if (!JSVAL_IS_STRING(id))        return JS_TRUE;    /* No valid function object should lack private data, but check anyway. */    fun = (JSFunction *)JS_GetInstancePrivate(cx, obj, &js_FunctionClass, NULL);    if (!fun || !fun->object)        return JS_TRUE;    /*     * Ok, check whether id is 'prototype' and bootstrap the function object's     * prototype property.     */    str = JSVAL_TO_STRING(id);    prototypeAtom = cx->runtime->atomState.classPrototypeAtom;    if (str == ATOM_TO_STRING(prototypeAtom)) {        JSObject *proto, *parentProto;        jsval pval;        proto = parentProto = NULL;        if (fun->object != obj && fun->object) {            /*             * Clone of a function: make its prototype property value have the             * same class as the clone-parent's prototype.             */            if (!OBJ_GET_PROPERTY(cx, fun->object, ATOM_TO_JSID(prototypeAtom),                                  &pval)) {                return JS_FALSE;            }            if (!JSVAL_IS_PRIMITIVE(pval)) {                /*                 * We are about to allocate a new object, so hack the newborn                 * root until then to protect pval in case it is figuratively                 * up in the air, with no strong refs protecting it.                 */                cx->weakRoots.newborn[GCX_OBJECT] = JSVAL_TO_GCTHING(pval);                parentProto = JSVAL_TO_OBJECT(pval);            }        }        /*         * Beware of the wacky case of a user function named Object -- trying         * to find a prototype for that will recur back here _ad perniciem_.         */        if (!parentProto && fun->atom == CLASS_ATOM(cx, Object))            return JS_TRUE;        /*         * If resolving "prototype" in a clone, clone the parent's prototype.         * Pass the constructor's (obj's) parent as the prototype parent, to         * avoid defaulting to parentProto.constructor.__parent__.         */        proto = js_NewObject(cx, &js_ObjectClass, parentProto,                             OBJ_GET_PARENT(cx, obj));        if (!proto)            return JS_FALSE;        /*         * ECMA (15.3.5.2) says that constructor.prototype is DontDelete for         * user-defined functions, but DontEnum | ReadOnly | DontDelete for         * native "system" constructors such as Object or Function.  So lazily         * set the former here in fun_resolve, but eagerly define the latter         * in JS_InitClass, with the right attributes.         */        if (!js_SetClassPrototype(cx, obj, proto,                                  JSPROP_ENUMERATE | JSPROP_PERMANENT)) {            cx->weakRoots.newborn[GCX_OBJECT] = NULL;            return JS_FALSE;        }        *objp = obj;    }    return JS_TRUE;}static JSBoolfun_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp){    switch (type) {      case JSTYPE_FUNCTION:        *vp = OBJECT_TO_JSVAL(obj);        return JS_TRUE;      default:        return js_TryValueOf(cx, obj, type, vp);    }}static voidfun_finalize(JSContext *cx, JSObject *obj){    JSFunction *fun;    JSScript *script;    /* No valid function object should lack private data, but check anyway. */    fun = (JSFunction *) JS_GetPrivate(cx, obj);    if (!fun)        return;    if (fun->object == obj)        fun->object = NULL;    /* Null-check required since the parser sets interpreted very early. */    if (FUN_INTERPRETED(fun) && fun->u.i.script &&        js_IsAboutToBeFinalized(cx, fun))    {        script = fun->u.i.script;        fun->u.i.script = NULL;        js_DestroyScript(cx, script);    }}#if JS_HAS_XDR#include "jsxdrapi.h"enum {    JSXDR_FUNARG = 1,    JSXDR_FUNVAR = 2,    JSXDR_FUNCONST = 3};/* XXX store parent and proto, if defined */static JSBoolfun_xdrObject(JSXDRState *xdr, JSObject **objp){    JSContext *cx;    JSFunction *fun;

⌨️ 快捷键说明

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