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

📄 jsinterp.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 5 页
字号:
            sp = vp + 4;            if (argc < 2) {                a = cx->stackPool.current;                if ((jsuword)sp > a->limit) {                    /*                     * Arguments must be contiguous, and must include argv[-1]                     * and argv[-2], so allocate more stack, advance sp, and                     * set newsp[1] to thisp (vp[1]).  The other argv elements                     * will be set below, using negative indexing from sp.                     */                    newsp = js_AllocRawStack(cx, 4, NULL);                    if (!newsp) {                        ok = JS_FALSE;                        goto out2;                    }                    newsp[1] = OBJECT_TO_JSVAL(thisp);                    sp = newsp + 4;                } else if ((jsuword)sp > a->avail) {                    /*                     * Inline, optimized version of JS_ARENA_ALLOCATE to claim                     * the small number of words not already allocated as part                     * of the caller's operand stack.                     */                    JS_ArenaCountAllocation(pool, (jsuword)sp - a->avail);                    a->avail = (jsuword)sp;                }            }            sp[-4] = v;            JS_ASSERT(sp[-3] == OBJECT_TO_JSVAL(thisp));            sp[-2] = ATOM_KEY(atom);            sp[-1] = OBJECT_TO_JSVAL(argsobj);            fp->sp = sp;            argc = 2;            break;          default:            goto bad;        }#else        goto bad;#endif    }    funobj = JSVAL_TO_OBJECT(v);    parent = OBJ_GET_PARENT(cx, funobj);    clasp = OBJ_GET_CLASS(cx, funobj);    if (clasp != &js_FunctionClass) {        /* Function is inlined, all other classes use object ops. */        ops = funobj->map->ops;        /*         * XXX         * Try converting to function, for closure and API compatibility.         * We attempt the conversion under all circumstances for 1.2, but         * only if there is a call op defined otherwise.         */        if (cx->version == JSVERSION_1_2 ||            ((ops == &js_ObjectOps) ? clasp->call : ops->call)) {            ok = clasp->convert(cx, funobj, JSTYPE_FUNCTION, &v);            if (!ok)                goto out2;            if (JSVAL_IS_FUNCTION(cx, v)) {                /* Make vp refer to funobj to keep it available as argv[-2]. */                *vp = v;                funobj = JSVAL_TO_OBJECT(v);                parent = OBJ_GET_PARENT(cx, funobj);                goto have_fun;            }        }        fun = NULL;        script = NULL;	swf = NULL;        minargs = nvars = 0;        /* Try a call or construct native object op. */        native = (flags & JSINVOKE_CONSTRUCT) ? ops->construct : ops->call;        if (!native)            goto bad;    } else {have_fun:        /* Get private data and set derived locals from it. */        fun = (JSFunction *) JS_GetPrivate(cx, funobj);        native = fun->native;        script = fun->script;	swf = fun->swf;        minargs = fun->nargs + fun->extra;        nvars = fun->nvars;        /* Handle bound method special case. */        if (fun->flags & JSFUN_BOUND_METHOD)            thisp = parent;    }    /* Initialize the rest of frame, except for sp (set by SAVE_SP later). */    frame.varobj = NULL;    frame.callobj = frame.argsobj = NULL;    frame.script = script;    frame.swf = swf;    frame.fun = fun;    frame.argc = argc;    frame.argv = sp - argc;    frame.nvars = nvars;    frame.vars = sp;    frame.down = fp;    frame.annotation = NULL;    frame.scopeChain = NULL;    /* set below for real, after cx->fp is set */    frame.pc = NULL;    frame.spbase = NULL;    frame.spend = NULL;    frame.sharpDepth = 0;    frame.sharpArray = NULL;    frame.dormantNext = NULL;    frame.objAtomMap = NULL;    frame.constant_pool = NULL;    /* Compute the 'this' parameter and store it in frame as frame.thisp. */    ok = ComputeThis(cx, thisp, &frame);    if (!ok)        goto out2;    /* From here on, control must flow through label out: to return. */    cx->fp = &frame;    /* Init these now in case we goto out before first hook call. */    hook = cx->runtime->callHook;    hookData = NULL;    /* Check for missing arguments expected by the function. */    nslots = (intN)((argc < minargs) ? minargs - argc : 0);    if (nslots) {        /* All arguments must be contiguous, so we may have to copy actuals. */        nalloc = nslots;        limit = (jsval *) cx->stackPool.current->limit;        if (sp + nslots > limit) {            /* Hit end of arena: we have to copy argv[-2..(argc+nslots-1)]. */            nalloc += 2 + argc;        } else {            /* Take advantage of surplus slots in the caller's frame depth. */            surplus = (jsval *)mark - sp;            JS_ASSERT(surplus >= 0);            nalloc -= surplus;        }        /* Check whether we have enough space in the caller's frame. */        if (nalloc > 0) {            /* Need space for actuals plus missing formals minus surplus. */            newsp = js_AllocRawStack(cx, (uintN)nalloc, NULL);            if (!newsp) {                ok = JS_FALSE;                goto out;            }            /* If we couldn't allocate contiguous args, copy actuals now. */            if (newsp != mark) {                JS_ASSERT(sp + nslots > limit);                JS_ASSERT(2 + argc + nslots == (uintN)nalloc);                *newsp++ = vp[0];                *newsp++ = vp[1];                if (argc)                    memcpy(newsp, frame.argv, argc * sizeof(jsval));                frame.argv = newsp;                sp = frame.vars = newsp + argc;            }        }        /* Advance frame.vars to make room for the missing args. */        frame.vars += nslots;        /* Push void to initialize missing args. */        while (--nslots >= 0)            PUSH(JSVAL_VOID);    }    /* Now allocate stack space for local variables. */    nslots = (intN)frame.nvars;    if (nslots) {        surplus = (intN)((jsval *)cx->stackPool.current->avail - frame.vars);        if (surplus < nslots) {            newsp = js_AllocRawStack(cx, (uintN)nslots, NULL);            if (!newsp) {                ok = JS_FALSE;                goto out;            }            if (newsp != sp) {                /* NB: Discontinuity between argv and vars. */                sp = frame.vars = newsp;            }        }        /* Push void to initialize local variables. */        while (--nslots >= 0)            PUSH(JSVAL_VOID);    }    /* Store the current sp in frame before calling fun. */    SAVE_SP(&frame);    /* call the hook if present */    if (hook && (native || script))        hookData = hook(cx, &frame, JS_TRUE, 0, cx->runtime->callHookData);    /* Call the function, either a native method or an interpreted script. */    if (native) {#if JS_HAS_LVALUE_RETURN        /* Set by JS_SetCallReturnValue2, used to return reference types. */        cx->rval2set = JS_FALSE;#endif        /* If native, use caller varobj and scopeChain for eval. */        frame.varobj = fp->varobj;        frame.scopeChain = fp->scopeChain;        ok = native(cx, frame.thisp, argc, frame.argv, &frame.rval);        JS_RUNTIME_METER(cx->runtime, nativeCalls);    } else if (script) {        /* Use parent scope so js_GetCallObject can find the right "Call". */        frame.scopeChain = parent;        if (fun->flags & JSFUN_HEAVYWEIGHT) {#if JS_HAS_CALL_OBJECT            /* Scope with a call object parented by the callee's parent. */            if (!js_GetCallObject(cx, &frame, parent)) {                ok = JS_FALSE;                goto out;            }#else            /* Bad old code used the function as a proxy for all calls to it. */            frame.scopeChain = funobj;#endif        }        ok = js_Interpret(cx, &v);    } else if (swf) {	if (!js_GetCallObject(cx, &frame, parent)) {	    ok = JS_FALSE;	    goto out;	}        ok = swfdec_script_interpret(swf, cx, &v);    } else {        /* fun might be onerror trying to report a syntax error in itself. */        frame.scopeChain = NULL;        ok = JS_TRUE;    }out:    if (hookData) {        hook = cx->runtime->callHook;        if (hook)            hook(cx, &frame, JS_FALSE, &ok, hookData);    }#if JS_HAS_CALL_OBJECT    /* If frame has a call object, sync values and clear back-pointer. */    if (frame.callobj)        ok &= js_PutCallObject(cx, &frame);#endif#if JS_HAS_ARGS_OBJECT    /* If frame has an arguments object, sync values and clear back-pointer. */    if (frame.argsobj)        ok &= js_PutArgsObject(cx, &frame);#endif    /* Restore cx->fp now that we're done releasing frame objects. */    cx->fp = fp;out2:    /* Pop everything we may have allocated off the stack. */    JS_ARENA_RELEASE(&cx->stackPool, mark);    /* Store the return value and restore sp just above it. */    *vp = frame.rval;    fp->sp = vp + 1;    /*     * Store the location of the JSOP_CALL or JSOP_EVAL that generated the     * return value, but only if this is an external (compiled from script     * source) call that has stack budget for the generating pc.     */    if (fp->script && !(flags & JSINVOKE_INTERNAL))        vp[-(intN)fp->script->depth] = (jsval)fp->pc;    return ok;bad:    js_ReportIsNotFunction(cx, vp, flags & JSINVOKE_CONSTRUCT);    ok = JS_FALSE;    goto out2;}JSBooljs_InternalInvoke(JSContext *cx, JSObject *obj, jsval fval, uintN flags,                  uintN argc, jsval *argv, jsval *rval){    JSStackFrame *fp, *oldfp, frame;    jsval *oldsp, *sp;    void *mark;    uintN i;    JSBool ok;    fp = oldfp = cx->fp;    if (!fp) {        memset(&frame, 0, sizeof frame);        cx->fp = fp = &frame;    }    oldsp = fp->sp;    sp = js_AllocStack(cx, 2 + argc, &mark);    if (!sp) {        ok = JS_FALSE;        goto out;    }    PUSH(fval);    PUSH(OBJECT_TO_JSVAL(obj));    for (i = 0; i < argc; i++)        PUSH(argv[i]);    fp->sp = sp;    ok = js_Invoke(cx, argc, flags | JSINVOKE_INTERNAL);    if (ok) {        RESTORE_SP(fp);        *rval = POP_OPND();    }    js_FreeStack(cx, mark);out:    fp->sp = oldsp;    if (oldfp != fp)        cx->fp = oldfp;    return ok;}JSBooljs_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval,                    JSAccessMode mode, uintN argc, jsval *argv, jsval *rval){    /*     * Check general (not object-ops/class-specific) access from the running     * script to obj.id only if id has a scripted getter or setter that we're     * about to invoke.  If we don't check this case, nothing else will -- no     * other native code has the chance to check.     *     * Contrast this non-native (scripted) case with native getter and setter     * accesses, where the native itself must do an access check, if security     * policies requires it.  We make a checkAccess or checkObjectAccess call     * back to the embedding program only in those cases where we're not going     * to call an embedding-defined native function, getter, setter, or class     * hook anyway.  Where we do call such a native, there's no need for the     * engine to impose a separate access check callback on all embeddings --     * many embeddings have no security policy at all.     */    JS_ASSERT(mode == JSACC_READ || mode == JSACC_WRITE);    if (cx->runtime->checkObjectAccess &&        JSVAL_IS_FUNCTION(cx, fval) &&        ((JSFunction *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(fval)))->script &&        !cx->runtime->checkObjectAccess(cx, obj, ID_TO_VALUE(id), mode,                                        &fval)) {        return JS_FALSE;    }    return js_InternalCall(cx, obj, fval, argc, argv, rval);}JSBooljs_Execute(JSContext *cx, JSObject *chain, JSScript *script,           JSStackFrame *down, uintN special, jsval *result){    JSStackFrame *oldfp, frame;    JSObject *obj, *tmp;    JSBool ok;    JSInterpreterHook hook;    void *hookData;

⌨️ 快捷键说明

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