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

📄 jsfun.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 5 页
字号:
                return JS_FALSE;            }        }        js_CallNewScriptHook(cx, fun->script, fun);    }    return JS_TRUE;}#else  /* !JS_HAS_XDR */#define fun_xdrObject NULL#endif /* !JS_HAS_XDR */#if JS_HAS_INSTANCEOF/* * [[HasInstance]] internal method for Function objects: fetch the .prototype * property of its 'this' parameter, and walks the prototype chain of v (only * if v is an object) returning true if .prototype is found. */static JSBoolfun_hasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp){    jsval pval, cval;    JSString *str;    JSObject *proto, *obj2;    JSFunction *cfun, *ofun;    if (!OBJ_GET_PROPERTY(cx, obj,                          (jsid)cx->runtime->atomState.classPrototypeAtom,                          &pval)) {        return JS_FALSE;    }    if (JSVAL_IS_PRIMITIVE(pval)) {        /*         * Throw a runtime error if instanceof is called on a function that         * has a non-object as its .prototype value.         */        str = js_DecompileValueGenerator(cx, -1, OBJECT_TO_JSVAL(obj), NULL);        if (str) {            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                                 JSMSG_BAD_PROTOTYPE, JS_GetStringBytes(str));        }        return JS_FALSE;    }    proto = JSVAL_TO_OBJECT(pval);    if (!js_IsDelegate(cx, proto, v, bp))        return JS_FALSE;    if (!*bp && !JSVAL_IS_PRIMITIVE(v) && v != pval) {        /*         * Extension for "brutal sharing" of standard class constructors: if         * a script is compiled using a single, shared set of constructors, in         * particular Function and RegExp, but executed many times using other         * sets of standard constructors, then (/re/ instanceof RegExp), e.g.,         * will be false.         *         * We extend instanceof in this case to look for a matching native or         * script underlying the function object found in the 'constructor'         * property of the object in question (which is JSVAL_TO_OBJECT(v)),         * or found in the 'constructor' property of one of its prototypes.         *         * See also jsexn.c, where the *Error constructors are defined, each         * with its own native function, to satisfy (e instanceof Error) even         * when exceptions cross standard-class sharing boundaries.  Note that         * Error.prototype may not lie on e's __proto__ chain in that case.         */        obj2 = JSVAL_TO_OBJECT(v);        do {            if (!OBJ_GET_PROPERTY(cx, obj2,                                  (jsid)cx->runtime->atomState.constructorAtom,                                  &cval)) {                return JS_FALSE;            }            if (JSVAL_IS_FUNCTION(cx, cval)) {                cfun = (JSFunction *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(cval));                ofun = (JSFunction *) JS_GetPrivate(cx, obj);                if (cfun->native == ofun->native &&                    cfun->script == ofun->script) {                    *bp = JS_TRUE;                    break;                }            }        } while ((obj2 = OBJ_GET_PROTO(cx, obj2)) != NULL);    }    return JS_TRUE;}#else  /* !JS_HAS_INSTANCEOF */#define fun_hasInstance NULL#endif /* !JS_HAS_INSTANCEOF */static uint32fun_mark(JSContext *cx, JSObject *obj, void *arg){    JSFunction *fun;    fun = (JSFunction *) JS_GetPrivate(cx, obj);    if (fun) {        if (fun->atom)            GC_MARK_ATOM(cx, fun->atom, arg);        if (fun->script)            js_MarkScript(cx, fun->script, arg);    }    return 0;}/* * Reserve two slots in all function objects for XPConnect.  Note that this * does not bloat every instance, only those on which reserved slots are set, * and those on which ad-hoc properties are defined. */JSClass js_FunctionClass = {    js_Function_str,    JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(2),    JS_PropertyStub,  JS_PropertyStub,    fun_getProperty,  JS_PropertyStub,    JS_EnumerateStub, (JSResolveOp)fun_resolve,    fun_convert,      fun_finalize,    NULL,             NULL,    NULL,             NULL,    fun_xdrObject,    fun_hasInstance,    fun_mark,         0};JSBooljs_fun_toString(JSContext *cx, JSObject *obj, uint32 indent,                uintN argc, jsval *argv, jsval *rval){    jsval fval;    JSFunction *fun;    JSString *str;    if (!argv) {        JS_ASSERT(JS_ObjectIsFunction(cx, obj));    } else {        fval = argv[-1];        if (!JSVAL_IS_FUNCTION(cx, fval)) {            /*             * If we don't have a function to start off with, try converting             * the object to a function.  If that doesn't work, complain.             */            if (JSVAL_IS_OBJECT(fval)) {                obj = JSVAL_TO_OBJECT(fval);                if (!OBJ_GET_CLASS(cx, obj)->convert(cx, obj, JSTYPE_FUNCTION,                                                     &fval)) {                    return JS_FALSE;                }            }            if (!JSVAL_IS_FUNCTION(cx, fval)) {                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                                     JSMSG_INCOMPATIBLE_PROTO,                                     js_Function_str, js_toString_str,                                     JS_GetTypeName(cx,                                                    JS_TypeOfValue(cx, fval)));                return JS_FALSE;            }        }        obj = JSVAL_TO_OBJECT(fval);    }    fun = (JSFunction *) JS_GetPrivate(cx, obj);    if (!fun)        return JS_TRUE;    if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent))        return JS_FALSE;    str = JS_DecompileFunction(cx, fun, (uintN)indent);    if (!str)        return JS_FALSE;    *rval = STRING_TO_JSVAL(str);    return JS_TRUE;}static JSBoolfun_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    JSString *string = JS_InternString (cx, "[type Function]");    if (string == NULL)	return JS_FALSE;    *rval = STRING_TO_JSVAL (string);    return JS_TRUE;}#if JS_HAS_TOSOURCEstatic JSBoolfun_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    return js_fun_toString(cx, obj, JS_DONT_PRETTY_PRINT, argc, argv, rval);}#endifstatic const char js_call_str[] = "call";#if JS_HAS_CALL_FUNCTIONstatic JSBoolfun_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    jsval fval, *sp, *oldsp;    void *mark;    uintN i;    JSStackFrame *fp;    JSBool ok;    if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &argv[-1]))        return JS_FALSE;    fval = argv[-1];    if (!JSVAL_IS_FUNCTION(cx, fval)) {        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                             JSMSG_INCOMPATIBLE_PROTO,                             js_Function_str, js_call_str,                             JS_GetStringBytes(JS_ValueToString(cx, fval)));        return JS_FALSE;    }    if (argc == 0) {        /* Call fun with its parent as the 'this' parameter if no args. */        obj = OBJ_GET_PARENT(cx, obj);    } else {        /* Otherwise convert the first arg to 'this' and skip over it. */        if (!js_ValueToObject(cx, argv[0], &obj))            return JS_FALSE;        argc--;        argv++;    }    /* Allocate stack space for fval, obj, and the args. */    sp = js_AllocStack(cx, 2 + argc, &mark);    if (!sp)        return JS_FALSE;    /* Push fval, obj, and the args. */    *sp++ = fval;    *sp++ = OBJECT_TO_JSVAL(obj);    for (i = 0; i < argc; i++)        *sp++ = argv[i];    /* Lift current frame to include the args and do the call. */    fp = cx->fp;    oldsp = fp->sp;    fp->sp = sp;    ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL | JSINVOKE_SKIP_CALLER);    /* Store rval and pop stack back to our frame's sp. */    *rval = fp->sp[-1];    fp->sp = oldsp;    js_FreeStack(cx, mark);    return ok;}#endif /* JS_HAS_CALL_FUNCTION */#if JS_HAS_APPLY_FUNCTIONstatic JSBoolfun_apply(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    jsval fval, *sp, *oldsp;    JSObject *aobj;    jsuint length;    void *mark;    uintN i;    JSBool ok;    JSStackFrame *fp;    if (argc == 0) {        /* Will get globalObject as 'this' and no other arguments. */        return fun_call(cx, obj, argc, argv, rval);    }    if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &argv[-1]))        return JS_FALSE;    fval = argv[-1];    if (!JSVAL_IS_FUNCTION(cx, fval)) {        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                             JSMSG_INCOMPATIBLE_PROTO,                             js_Function_str, "apply",                             JS_GetStringBytes(JS_ValueToString(cx, fval)));        return JS_FALSE;    }    /* Quell GCC overwarnings. */    aobj = NULL;    length = 0;    if (argc >= 2) {        /* If the 2nd arg is null or void, call the function with 0 args. */        if (JSVAL_IS_NULL(argv[1]) || JSVAL_IS_VOID(argv[1])) {            argc = 0;        } else {            /* The second arg must be an array (or arguments object). */            if (JSVAL_IS_PRIMITIVE(argv[1]) ||                (aobj = JSVAL_TO_OBJECT(argv[1]),                OBJ_GET_CLASS(cx, aobj) != &js_ArgumentsClass &&                OBJ_GET_CLASS(cx, aobj) != &js_ArrayClass))            {                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                                     JSMSG_BAD_APPLY_ARGS);                return JS_FALSE;            }            if (!js_GetLengthProperty(cx, aobj, &length))                return JS_FALSE;        }    }    /* Convert the first arg to 'this' and skip over it. */    if (!js_ValueToObject(cx, argv[0], &obj))        return JS_FALSE;    /* Allocate stack space for fval, obj, and the args. */    argc = (uintN)JS_MIN(length, ARGC_LIMIT - 1);    sp = js_AllocStack(cx, 2 + argc, &mark);    if (!sp)        return JS_FALSE;    /* Push fval, obj, and aobj's elements as args. */    *sp++ = fval;    *sp++ = OBJECT_TO_JSVAL(obj);    for (i = 0; i < argc; i++) {        ok = JS_GetElement(cx, aobj, (jsint)i, sp);        if (!ok)            goto out;        sp++;    }    /* Lift current frame to include the args and do the call. */    fp = cx->fp;    oldsp = fp->sp;    fp->sp = sp;    ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL | JSINVOKE_SKIP_CALLER);    /* Store rval and pop stack back to our frame's sp. */    *rval = fp->sp[-1];    fp->sp = oldsp;out:    js_FreeStack(cx, mark);    return ok;}#endif /* JS_HAS_APPLY_FUNCTION */static JSFunctionSpec function_methods[] = {#if JS_HAS_TOSOURCE    {js_toSource_str,   fun_toSource,   0,0,0},#endif    {js_toString_str,   fun_toString,   1,0,0},#if JS_HAS_APPLY_FUNCTION    {"apply",           fun_apply,      2,0,0},#endif#if JS_HAS_CALL_FUNCTION    {js_call_str,       fun_call,       1,0,0},#endif    {0,0,0,0,0}};JSBooljs_IsIdentifier(JSString *str){    size_t n;    jschar *s, c;    n = JSSTRING_LENGTH(str);    if (n == 0)        return JS_FALSE;    s = JSSTRING_CHARS(str);    c = *s;    if (!JS_ISIDENT_START(c))        return JS_FALSE;    for (n--; n != 0; n--) {        c = *++s;        if (!JS_ISIDENT(c))            return JS_FALSE;    }    return JS_TRUE;}static JSBoolFunction(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){    JSStackFrame *fp, *caller;    JSFunction *fun;    JSObject *parent;    uintN i, n, lineno, dupflag;    JSAtom *atom;    const char *filename;    JSObject *obj2;    JSScopeProperty *sprop;    JSString *str, *arg;    void *mark;    JSTokenStream *ts;    JSPrincipals *principals;    jschar *collected_args, *cp;    size_t arg_length, args_length;    JSTokenType tt;    JSBool ok;    fp = cx->fp;    if (fp && !(fp->flags & JSFRAME_CONSTRUCTING)) {        obj = js_NewObject(cx, &js_FunctionClass, NULL, NULL);        if (!obj)            return JS_FALSE;        *rval = OBJECT_TO_JSVAL(obj);    }    fun = (JSFunction *) JS_GetPrivate(cx, obj);

⌨️ 快捷键说明

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