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

📄 jsfun.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 5 页
字号:
call_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,    JS_PropertyStub,  JS_PropertyStub,    call_getProperty, call_setProperty,    call_enumerate,   (JSResolveOp)call_resolve,    call_convert,     JS_FinalizeStub,    JSCLASS_NO_OPTIONAL_MEMBERS};#endif /* JS_HAS_CALL_OBJECT *//* SHARED because fun_getProperty always computes a new value. */#define FUNCTION_PROP_ATTRS (JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED)static JSPropertySpec function_props[] = {    {js_arguments_str, CALL_ARGUMENTS, FUNCTION_PROP_ATTRS,0,0},    {js_arity_str,     FUN_ARITY,      FUNCTION_PROP_ATTRS,0,0},    {js_length_str,    ARGS_LENGTH,    FUNCTION_PROP_ATTRS,0,0},    {js_name_str,      FUN_NAME,       FUNCTION_PROP_ATTRS,0,0},    {js_caller_str,    FUN_CALLER,     FUNCTION_PROP_ATTRS,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 defined _MSC_VER &&_MSC_VER <= 800    /* MSVC1.5 coredumps */    jsval bogus = *vp;#endif    if (!JSVAL_IS_INT(id))        return JS_TRUE;    slot = JSVAL_TO_INT(id);    /* No valid function object should lack private data, but check anyway. */    fun = (JSFunction *)JS_GetInstancePrivate(cx, obj, &js_FunctionClass, NULL);    if (!fun)        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:#if JS_HAS_ARGS_OBJECT        /* 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;#else  /* !JS_HAS_ARGS_OBJECT */        *vp = OBJECT_TO_JSVAL(fp ? obj : NULL);        break;#endif /* !JS_HAS_ARGS_OBJECT */      case ARGS_LENGTH:        if (!JSVERSION_IS_ECMA(cx->version))            *vp = INT_TO_JSVAL((jsint)(fp && fp->fun ? fp->argc : fun->nargs));        else      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)#if defined _MSC_VER &&_MSC_VER <= 800          /* MSVC1.5 coredumps */          if (bogus == *vp)#endif            *vp = fp->argv[slot];        break;    }    return JS_TRUE;}static JSBoolfun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,            JSObject **objp){    JSFunction *fun;    JSString *str;    JSAtom *prototypeAtom;    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;    /* No need to reflect fun.prototype in 'fun.prototype = ...'. */    if (flags & JSRESOLVE_ASSIGNING)        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, (jsid)prototypeAtom, &pval))                return JS_FALSE;            if (JSVAL_IS_OBJECT(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 == cx->runtime->atomState.ObjectAtom)            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->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);    }}struct _SwfdecScript {  JSFunction *		fun;};extern void swfdec_script_unref (void *script);static voidfun_finalize(JSContext *cx, JSObject *obj){    JSFunction *fun;    /* 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;    JS_ATOMIC_DECREMENT(&fun->nrefs);    if (fun->nrefs)        return;    if (fun->script)        js_DestroyScript(cx, fun->script);    if (fun->swf) {	((struct _SwfdecScript *) fun->swf)->fun = NULL;	swfdec_script_unref (fun->swf);    }    JS_free(cx, fun);}#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;    JSString *atomstr;    char *propname;    JSScopeProperty *sprop;    uint32 userid;              /* NB: holds a signed int-tagged jsval */    JSAtom *atom;    uintN i, n, dupflag;    uint32 type;#ifdef DEBUG    uintN nvars = 0, nargs = 0;#endif    cx = xdr->cx;    if (xdr->mode == JSXDR_ENCODE) {        /*         * No valid function object should lack private data, but fail soft         * (return true, no error report) in case one does due to API pilot         * or internal error.         */        fun = (JSFunction *) JS_GetPrivate(cx, *objp);        if (!fun)            return JS_TRUE;        atomstr = fun->atom ? ATOM_TO_STRING(fun->atom) : NULL;    } else {        fun = js_NewFunction(cx, NULL, NULL, 0, 0, NULL, NULL);        if (!fun)            return JS_FALSE;        atomstr = NULL;    }    if (!JS_XDRStringOrNull(xdr, &atomstr) ||        !JS_XDRUint16(xdr, &fun->nargs) ||        !JS_XDRUint16(xdr, &fun->extra) ||        !JS_XDRUint16(xdr, &fun->nvars) ||        !JS_XDRUint8(xdr, &fun->flags)) {        return JS_FALSE;    }    /* do arguments and local vars */    if (fun->object) {        n = fun->nargs + fun->nvars;        if (xdr->mode == JSXDR_ENCODE) {            JSScope *scope;            JSScopeProperty **spvec, *auto_spvec[8];            void *mark;            if (n <= sizeof auto_spvec / sizeof auto_spvec[0]) {                spvec = auto_spvec;                mark = NULL;            } else {                mark = JS_ARENA_MARK(&cx->tempPool);                JS_ARENA_ALLOCATE_CAST(spvec, JSScopeProperty **, &cx->tempPool,                                       n * sizeof(JSScopeProperty *));                if (!spvec) {                    JS_ReportOutOfMemory(cx);                    return JS_FALSE;                }            }            scope = OBJ_SCOPE(fun->object);            for (sprop = SCOPE_LAST_PROP(scope); sprop;                 sprop = sprop->parent) {                if (sprop->getter == js_GetArgument) {                    JS_ASSERT(nargs++ <= fun->nargs);                    spvec[sprop->shortid] = sprop;                } else if (sprop->getter == js_GetLocalVariable) {                    JS_ASSERT(nvars++ <= fun->nvars);                    spvec[fun->nargs + sprop->shortid] = sprop;                }            }            for (i = 0; i < n; i++) {                sprop = spvec[i];                JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);                type = (i < fun->nargs)                       ? JSXDR_FUNARG                       : (sprop->attrs & JSPROP_READONLY)                       ? JSXDR_FUNCONST                       : JSXDR_FUNVAR;                userid = INT_TO_JSVAL(sprop->shortid);                /* XXX lossy conversion, need new XDR version for ECMAv3 */                propname = JS_GetStringBytes(ATOM_TO_STRING((JSAtom *)sprop->id));                if (!propname ||                    !JS_XDRUint32(xdr, &type) ||                    !JS_XDRUint32(xdr, &userid) ||                    !JS_XDRCString(xdr, &propname)) {                    if (mark)                        JS_ARENA_RELEASE(&cx->tempPool, mark);                    return JS_FALSE;                }            }            if (mark)                JS_ARENA_RELEASE(&cx->tempPool, mark);        } else {            JSPropertyOp getter, setter;            for (i = n; i != 0; i--) {                uintN attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;                if (!JS_XDRUint32(xdr, &type) ||                    !JS_XDRUint32(xdr, &userid) ||                    !JS_XDRCString(xdr, &propname)) {                    return JS_FALSE;                }                JS_ASSERT(type == JSXDR_FUNARG || type == JSXDR_FUNVAR ||                          type == JSXDR_FUNCONST);                if (type == JSXDR_FUNARG) {                    getter = js_GetArgument;                    setter = js_SetArgument;                    JS_ASSERT(nargs++ <= fun->nargs);                } else if (type == JSXDR_FUNVAR || type == JSXDR_FUNCONST) {                    getter = js_GetLocalVariable;                    setter = js_SetLocalVariable;                    if (type == JSXDR_FUNCONST)                        attrs |= JSPROP_READONLY;                    JS_ASSERT(nvars++ <= fun->nvars);                } else {                    getter = NULL;                    setter = NULL;                }                atom = js_Atomize(cx, propname, strlen(propname), 0);                JS_free(cx, propname);                if (!atom)                    return JS_FALSE;                /* Flag duplicate argument if atom is bound in fun->object. */                dupflag = SCOPE_GET_PROPERTY(OBJ_SCOPE(fun->object), (jsid)atom)                          ? SPROP_IS_DUPLICATE                          : 0;                if (!js_AddNativeProperty(cx, fun->object, (jsid)atom,                                          getter, setter, SPROP_INVALID_SLOT,                                          attrs | JSPROP_SHARED,                                          SPROP_HAS_SHORTID | dupflag,                                          JSVAL_TO_INT(userid))) {                    return JS_FALSE;                }            }        }    }    if (!js_XDRScript(xdr, &fun->script, NULL))        return JS_FALSE;    if (xdr->mode == JSXDR_DECODE) {        *objp = fun->object;        if (atomstr) {            fun->atom = js_AtomizeString(cx, atomstr, 0);            if (!fun->atom)                return JS_FALSE;            if (!OBJ_DEFINE_PROPERTY(cx, cx->globalObject,                                     (jsid)fun->atom, OBJECT_TO_JSVAL(*objp),                                     NULL, NULL, JSPROP_ENUMERATE,                                     NULL)) {

⌨️ 快捷键说明

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