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

📄 jsfun.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
                                 JSMSG_INCOMPATIBLE_PROTO,                                 js_Function_str, "apply",                                 JS_GetStringBytes(str));        }        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). */            arraylike = JS_FALSE;            if (!JSVAL_IS_PRIMITIVE(argv[1])) {                aobj = JSVAL_TO_OBJECT(argv[1]);                if (!js_IsArrayLike(cx, aobj, &arraylike, &length))                    return JS_FALSE;            }            if (!arraylike) {                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                                     JSMSG_BAD_APPLY_ARGS, "apply");                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, ARRAY_INIT_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;}#ifdef NARCISSUSstatic JSBoolfun_applyConstructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,                     jsval *rval){    JSObject *aobj;    uintN length, i;    void *mark;    jsval *sp, *newsp, *oldsp;    JSStackFrame *fp;    JSBool ok;    if (JSVAL_IS_PRIMITIVE(argv[0]) ||        (aobj = JSVAL_TO_OBJECT(argv[0]),         OBJ_GET_CLASS(cx, aobj) != &js_ArrayClass &&         OBJ_GET_CLASS(cx, aobj) != &js_ArgumentsClass)) {        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                             JSMSG_BAD_APPLY_ARGS, "__applyConstruct__");        return JS_FALSE;    }    if (!js_GetLengthProperty(cx, aobj, &length))        return JS_FALSE;    if (length >= ARRAY_INIT_LIMIT)        length = ARRAY_INIT_LIMIT - 1;    newsp = sp = js_AllocStack(cx, 2 + length, &mark);    if (!sp)        return JS_FALSE;    fp = cx->fp;    oldsp = fp->sp;    *sp++ = OBJECT_TO_JSVAL(obj);    *sp++ = JSVAL_NULL; /* This is filled automagically. */    for (i = 0; i < length; i++) {        ok = JS_GetElement(cx, aobj, (jsint)i, sp);        if (!ok)            goto out;        sp++;    }    oldsp = fp->sp;    fp->sp = sp;    ok = js_InvokeConstructor(cx, newsp, length);    *rval = fp->sp[-1];    fp->sp = oldsp;out:    js_FreeStack(cx, mark);    return ok;}#endifstatic JSFunctionSpec function_methods[] = {#if JS_HAS_TOSOURCE    {js_toSource_str,   fun_toSource,   0,0,0},#endif    {js_toString_str,   fun_toString,   1,0,0},    {"apply",           fun_apply,      2,0,0},    {call_str,          fun_call,       1,0,0},#ifdef NARCISSUS    {"__applyConstructor__", fun_applyConstructor, 1,0,0},#endif    {0,0,0,0,0}};JSBooljs_IsIdentifier(JSString *str){    size_t length;    jschar c, *chars, *end, *s;    length = JSSTRING_LENGTH(str);    if (length == 0)        return JS_FALSE;    chars = JSSTRING_CHARS(str);    c = *chars;    if (!JS_ISIDSTART(c))        return JS_FALSE;    end = chars + length;    for (s = chars + 1; s != end; ++s) {        c = *s;        if (!JS_ISIDENT(c))            return JS_FALSE;    }    return !js_IsKeyword(chars, length);}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;    JSProperty *prop;    JSScopeProperty *sprop;    JSString *str, *arg;    void *mark;    JSTokenStream *ts;    JSPrincipals *principals;    jschar *collected_args, *cp;    size_t arg_length, args_length, old_args_length;    JSTokenType tt;    JSBool ok;    fp = cx->fp;    if (!(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);    if (fun)        return JS_TRUE;    /*     * NB: (new Function) is not lexically closed by its caller, it's just an     * anonymous function in the top-level scope that its constructor inhabits.     * Thus 'var x = 42; f = new Function("return x"); print(f())' prints 42,     * and so would a call to f from another top-level's script or function.     *     * In older versions, before call objects, a new Function was adopted by     * its running context's globalObject, which might be different from the     * top-level reachable from scopeChain (in HTML frames, e.g.).     */    parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(argv[-2]));    fun = js_NewFunction(cx, obj, NULL, 0, JSFUN_LAMBDA, parent,                         cx->runtime->atomState.anonymousAtom);    if (!fun)        return JS_FALSE;    /*     * Function is static and not called directly by other functions in this     * file, therefore it is callable only as a native function by js_Invoke.     * Find the scripted caller, possibly skipping other native frames such as     * are built for Function.prototype.call or .apply activations that invoke     * Function indirectly from a script.     */    JS_ASSERT(!fp->script && fp->fun && fp->fun->u.n.native == Function);    caller = JS_GetScriptedCaller(cx, fp);    if (caller) {        filename = caller->script->filename;        lineno = js_PCToLineNumber(cx, caller->script, caller->pc);        principals = JS_EvalFramePrincipals(cx, fp, caller);    } else {        filename = NULL;        lineno = 0;        principals = NULL;    }    /* Belt-and-braces: check that the caller has access to parent. */    if (!js_CheckPrincipalsAccess(cx, parent, principals,                                  CLASS_ATOM(cx, Function))) {        return JS_FALSE;    }    n = argc ? argc - 1 : 0;    if (n > 0) {        /*         * Collect the function-argument arguments into one string, separated         * by commas, then make a tokenstream from that string, and scan it to         * get the arguments.  We need to throw the full scanner at the         * problem, because the argument string can legitimately contain         * comments and linefeeds.  XXX It might be better to concatenate         * everything up into a function definition and pass it to the         * compiler, but doing it this way is less of a delta from the old         * code.  See ECMA 15.3.2.1.         */        args_length = 0;        for (i = 0; i < n; i++) {            /* Collect the lengths for all the function-argument arguments. */            arg = js_ValueToString(cx, argv[i]);            if (!arg)                return JS_FALSE;            argv[i] = STRING_TO_JSVAL(arg);            /*             * Check for overflow.  The < test works because the maximum             * JSString length fits in 2 fewer bits than size_t has.             */            old_args_length = args_length;            args_length = old_args_length + JSSTRING_LENGTH(arg);            if (args_length < old_args_length) {                JS_ReportOutOfMemory(cx);                return JS_FALSE;            }        }        /* Add 1 for each joining comma and check for overflow (two ways). */        old_args_length = args_length;        args_length = old_args_length + n - 1;        if (args_length < old_args_length ||            args_length >= ~(size_t)0 / sizeof(jschar)) {            JS_ReportOutOfMemory(cx);            return JS_FALSE;        }        /*         * Allocate a string to hold the concatenated arguments, including room         * for a terminating 0.  Mark cx->tempPool for later release, to free         * collected_args and its tokenstream in one swoop.         */        mark = JS_ARENA_MARK(&cx->tempPool);        JS_ARENA_ALLOCATE_CAST(cp, jschar *, &cx->tempPool,                               (args_length+1) * sizeof(jschar));        if (!cp) {            JS_ReportOutOfMemory(cx);            return JS_FALSE;        }        collected_args = cp;        /*         * Concatenate the arguments into the new string, separated by commas.         */        for (i = 0; i < n; i++) {            arg = JSVAL_TO_STRING(argv[i]);            arg_length = JSSTRING_LENGTH(arg);            (void) js_strncpy(cp, JSSTRING_CHARS(arg), arg_length);            cp += arg_length;            /* Add separating comma or terminating 0. */            *cp++ = (i + 1 < n) ? ',' : 0;        }        /*         * Make a tokenstream (allocated from cx->tempPool) that reads from         * the given string.         */        ts = js_NewTokenStream(cx, collected_args, args_length, filename,                               lineno, principals);        if (!ts) {            JS_ARENA_RELEASE(&cx->tempPool, mark);            return JS_FALSE;        }        /* The argument string may be empty or contain no tokens. */        tt = js_GetToken(cx, ts);        if (tt != TOK_EOF) {            for (;;) {                /*                 * Check that it's a name.  This also implicitly guards against                 * TOK_ERROR, which was already reported.                 */                if (tt != TOK_NAME)                    goto bad_formal;                /*                 * Get the atom corresponding to the name from the tokenstream;                 * we're assured at this point that it's a valid identifier.                 */                atom = CURRENT_TOKEN(ts).t_atom;                if (!js_LookupHiddenProperty(cx, obj, ATOM_TO_JSID(atom),                                             &obj2, &prop)) {                    goto bad_formal;                }                sprop = (JSScopeProperty *) prop;                dupflag = 0;                if (sprop) {                    ok = JS_TRUE;                    if (obj2 == obj) {                        const char *name = js_AtomToPrintableString(cx, atom);                        /*                         * A duplicate parameter name. We force a duplicate                         * node on the SCOPE_LAST_PROP(scope) list with the                         * same id, distinguished by the SPROP_IS_DUPLICATE                         * flag, and not mapped by an entry in scope.                         */                        JS_ASSERT(sprop->getter == js_GetArgument);                        ok = name &&                             js_ReportCompileErrorNumber(cx, ts,                                                         JSREPORT_TS |                                                         JSREPORT_WARNING |                                                         JSREPORT_STRICT,                                                         JSMSG_DUPLICATE_FORMAL,                                                         name);                        dupflag = SPROP_IS_DUPLICATE;                    }                    OBJ_DROP_PROPERTY(cx, obj2, prop);                    if (!ok)                        goto bad_formal;                    sprop = NULL;                }                if (!js_AddHiddenProperty(cx, fun->object, ATOM_TO_JSID(atom),                                          js_GetArgument, js_SetArgument,                                          SPROP_INVALID_SLOT,                                          JSPROP_PERMANENT | JSPROP_SHARED,                                          dupflag | SPROP_HAS_SHORTID,                                          fun->nargs)) {                    goto bad_formal;                }                if (fun->nargs == JS_BITMASK(16)) {                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                                         JSMSG_TOO_MANY_FUN_ARGS);                    goto bad;                }                fun->nargs++;                /*                 * Get the next token.  Stop on end of stream.  Otherwise                 * insist on a comma, get another name, and iterate.                 */                tt = js_GetToken(cx, ts);                if (tt == TOK_EOF)                    break;                if (tt != TOK_COMMA)                    goto bad_formal;                tt = js_GetToken(cx, ts);            }        }        /* Clean up. */        ok = js_CloseTokenStream(cx, ts);        JS_ARENA_RELEASE(&cx->tempPool, mark);        if (!ok)            return JS_FALSE;    }    if (argc) {        str = js_ValueToString(cx, argv[argc-1]);    } else {        /* Can't use cx->runtime->emptyString because we're called too early. */        str = js_NewStringCopyZ(cx, js_empty_ucstr, 0);    }    if (!str)        return JS_FALSE;    if (argv) {        /* Use the last arg (or this if argc == 0) as a local GC root. */        argv[(intN)(argc-1)] = STRING_TO_JSVAL(str);    }    mark = JS_ARENA_MARK(&cx->tempPool);    ts = 

⌨️ 快捷键说明

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