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

📄 jsinterp.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 5 页
字号:
    hook = cx->runtime->executeHook;    hookData = NULL;    oldfp = cx->fp;    frame.callobj = frame.argsobj = NULL;    frame.script = script;    if (down) {        /* Propagate arg/var state for eval and the debugger API. */        frame.varobj = down->varobj;        frame.fun = down->fun;        frame.thisp = down->thisp;        frame.argc = down->argc;        frame.argv = down->argv;        frame.nvars = down->nvars;        frame.vars = down->vars;        frame.annotation = down->annotation;        frame.sharpArray = down->sharpArray;    } else {        obj = chain;        if (cx->options & JSOPTION_VAROBJFIX) {            while ((tmp = OBJ_GET_PARENT(cx, obj)) != NULL)                obj = tmp;        }        frame.varobj = obj;        frame.fun = NULL;        frame.thisp = chain;        frame.argc = frame.nvars = 0;        frame.argv = frame.vars = NULL;        frame.annotation = NULL;        frame.sharpArray = NULL;    }    frame.rval = JSVAL_VOID;    frame.down = down;    frame.scopeChain = chain;    frame.pc = NULL;    frame.sp = oldfp ? oldfp->sp : NULL;    frame.spbase = NULL;    frame.spend = NULL;    frame.sharpDepth = 0;    frame.flags = special;    frame.dormantNext = NULL;    frame.objAtomMap = NULL;    frame.constant_pool = NULL;    /*     * Here we wrap the call to js_Interpret with code to (conditionally)     * save and restore the old stack frame chain into a chain of 'dormant'     * frame chains.  Since we are replacing cx->fp, we were running into     * the problem that if GC was called under this frame, some of the GC     * things associated with the old frame chain (available here only in     * the C variable 'oldfp') were not rooted and were being collected.     *     * So, now we preserve the links to these 'dormant' frame chains in cx     * before calling js_Interpret and cleanup afterwards.  The GC walks     * these dormant chains and marks objects in the same way that it marks     * objects in the primary cx->fp chain.     */    if (oldfp && oldfp != down) {        JS_ASSERT(!oldfp->dormantNext);        oldfp->dormantNext = cx->dormantFrameChain;        cx->dormantFrameChain = oldfp;    }    cx->fp = &frame;    if (hook)        hookData = hook(cx, &frame, JS_TRUE, 0, cx->runtime->executeHookData);    /*     * Use frame.rval, not result, so the last result stays rooted across any     * GC activations nested within this js_Interpret.     */    ok = js_Interpret(cx, &frame.rval);    *result = frame.rval;    if (hookData) {        hook = cx->runtime->executeHook;        if (hook)            hook(cx, &frame, JS_FALSE, &ok, hookData);    }    cx->fp = oldfp;    if (oldfp && oldfp != down) {        JS_ASSERT(cx->dormantFrameChain == oldfp);        cx->dormantFrameChain = oldfp->dormantNext;        oldfp->dormantNext = NULL;    }    return ok;}#if JS_HAS_EXPORT_IMPORT/* * If id is JSVAL_VOID, import all exported properties from obj. */static JSBoolImportProperty(JSContext *cx, JSObject *obj, jsid id){    JSBool ok;    JSIdArray *ida;    JSProperty *prop;    JSObject *obj2, *target, *funobj, *closure;    JSString *str;    uintN attrs;    jsuint i;    jsval value;    if (JSVAL_IS_VOID(id)) {        ida = JS_Enumerate(cx, obj);        if (!ida)            return JS_FALSE;        ok = JS_TRUE;        if (ida->length == 0)            goto out;    } else {        ida = NULL;        if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))            return JS_FALSE;        if (!prop) {            str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK,                                             ID_TO_VALUE(id), NULL);            if (str)                js_ReportIsNotDefined(cx, JS_GetStringBytes(str));            return JS_FALSE;        }        ok = OBJ_GET_ATTRIBUTES(cx, obj, id, prop, &attrs);        OBJ_DROP_PROPERTY(cx, obj2, prop);        if (!ok)            return JS_FALSE;        if (!(attrs & JSPROP_EXPORTED)) {            str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK,                                             ID_TO_VALUE(id), NULL);            if (str) {                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                                     JSMSG_NOT_EXPORTED,                                     JS_GetStringBytes(str));            }            return JS_FALSE;        }    }    target = cx->fp->varobj;    i = 0;    do {        if (ida) {            id = ida->vector[i];            ok = OBJ_GET_ATTRIBUTES(cx, obj, id, NULL, &attrs);            if (!ok)                goto out;            if (!(attrs & JSPROP_EXPORTED))                continue;        }        ok = OBJ_CHECK_ACCESS(cx, obj, id, JSACC_IMPORT, &value, &attrs);        if (!ok)            goto out;        if (JSVAL_IS_FUNCTION(cx, value)) {            funobj = JSVAL_TO_OBJECT(value);            closure = js_CloneFunctionObject(cx, funobj, obj);            if (!closure) {                ok = JS_FALSE;                goto out;            }            value = OBJECT_TO_JSVAL(closure);        }        /*         * Handle the case of importing a property that refers to a local         * variable or formal parameter of a function activation.  These         * properties are accessed by opcodes using stack slot numbers         * generated by the compiler rather than runtime name-lookup.  These         * local references, therefore, bypass the normal scope chain lookup.         * So, instead of defining a new property in the activation object,         * modify the existing value in the stack slot.         */        if (OBJ_GET_CLASS(cx, target) == &js_CallClass) {            ok = OBJ_LOOKUP_PROPERTY(cx, target, id, &obj2, &prop);            if (!ok)                goto out;        } else {            prop = NULL;        }        if (prop && target == obj2) {            ok = OBJ_SET_PROPERTY(cx, target, id, &value);        } else {            ok = OBJ_DEFINE_PROPERTY(cx, target, id, value, NULL, NULL,                                     attrs & ~JSPROP_EXPORTED,                                     NULL);        }        if (prop)            OBJ_DROP_PROPERTY(cx, obj2, prop);        if (!ok)            goto out;    } while (ida && ++i < ida->length);out:    if (ida)        JS_DestroyIdArray(cx, ida);    return ok;}#endif /* JS_HAS_EXPORT_IMPORT */JSBooljs_CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs,                      JSBool *foundp){    JSObject *obj2;    JSProperty *prop;    JSBool ok;    uintN oldAttrs, report;    JSBool isFunction;    jsval value;    const char *type, *name;    if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))        return JS_FALSE;    *foundp = (prop != NULL);    if (!prop)        return JS_TRUE;    ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &oldAttrs);    OBJ_DROP_PROPERTY(cx, obj2, prop);    if (!ok)        return JS_FALSE;    /* If either property is readonly, we have an error. */    report = ((oldAttrs | attrs) & JSPROP_READONLY)             ? JSREPORT_ERROR             : JSREPORT_WARNING | JSREPORT_STRICT;    if (report != JSREPORT_ERROR) {        /*         * Allow redeclaration of variables and functions, but insist that the         * new value is not a getter if the old value was, ditto for setters --         * unless prop is impermanent (in which case anyone could delete it and         * redefine it, willy-nilly).         */        if (!(attrs & (JSPROP_GETTER | JSPROP_SETTER)))            return JS_TRUE;        if ((~(oldAttrs ^ attrs) & (JSPROP_GETTER | JSPROP_SETTER)) == 0)            return JS_TRUE;        if (!(oldAttrs & JSPROP_PERMANENT))            return JS_TRUE;        report = JSREPORT_ERROR;    }    isFunction = (oldAttrs & (JSPROP_GETTER | JSPROP_SETTER)) != 0;    if (!isFunction) {        if (!OBJ_GET_PROPERTY(cx, obj, id, &value))            return JS_FALSE;        isFunction = JSVAL_IS_FUNCTION(cx, value);    }    type = (oldAttrs & attrs & JSPROP_GETTER)           ? js_getter_str           : (oldAttrs & attrs & JSPROP_SETTER)           ? js_setter_str           : (oldAttrs & JSPROP_READONLY)           ? js_const_str           : isFunction           ? js_function_str           : js_var_str;    name = js_AtomToPrintableString(cx, (JSAtom *)id);    if (!name)        return JS_FALSE;    return JS_ReportErrorFlagsAndNumber(cx, report,                                        js_GetErrorMessage, NULL,                                        JSMSG_REDECLARED_VAR,                                        type, name);}#ifndef MAX_INTERP_LEVEL#if defined(XP_OS2)#define MAX_INTERP_LEVEL 250#elif defined _MSC_VER && _MSC_VER <= 800#define MAX_INTERP_LEVEL 30#else#define MAX_INTERP_LEVEL 1000#endif#endif#define MAX_INLINE_CALL_COUNT 1000JSBooljs_Interpret(JSContext *cx, jsval *result){    JSRuntime *rt;    JSStackFrame *fp;    JSScript *script;    uintN inlineCallCount;    JSObject *obj, *obj2, *proto, *parent;    JSVersion currentVersion, originalVersion;    JSBranchCallback onbranch;    JSBool ok, cond;    JSTrapHandler interruptHandler;    jsint depth, len;    jsval *sp = NULL, *newsp;    void *mark;    jsbytecode *pc, *pc2, *endpc;    JSOp op, op2;    const JSCodeSpec *cs = NULL;    JSAtom *atom;    uintN argc, slot, attrs;    jsval *vp, lval, rval, ltmp, rtmp;    jsid id = 0;    JSObject *withobj, *origobj, *propobj;    jsval iter_state;    JSProperty *prop;    JSScopeProperty *sprop;    JSString *str, *str2;    jsint i, j;    jsdouble d, d2;    const JSClass *clasp, *funclasp;    JSFunction *fun;    JSType type;#ifdef DEBUG    FILE *tracefp = NULL;#endif#if JS_HAS_EXPORT_IMPORT    JSIdArray *ida;#endif#if JS_HAS_SWITCH_STATEMENT    jsint low, high, off, npairs;    JSBool match;#endif#if JS_HAS_GETTER_SETTER    JSPropertyOp getter, setter;#endif    int stackDummy;    *result = JSVAL_VOID;    rt = cx->runtime;    /* Set registerized frame pointer and derived script pointer. */    fp = cx->fp;    script = fp->script;    /* Count of JS function calls that nest in this C js_Interpret frame. */    inlineCallCount = 0;    /*     * Optimized Get and SetVersion for proper script language versioning.     *     * If any native method or JSClass/JSObjectOps hook calls JS_SetVersion     * and changes cx->version, the effect will "stick" and we will stop     * maintaining currentVersion.  This is relied upon by testsuites, for     * the most part -- web browsers select version before compiling and not     * at run-time.     */    currentVersion = script->version;    originalVersion = cx->version;    if (currentVersion != originalVersion)        JS_SetVersion(cx, currentVersion);    /*     * Prepare to call a user-supplied branch handler, and abort the script     * if it returns false.  We reload onbranch after calling out to native     * functions (but not to getters, setters, or other native hooks).     */#define LOAD_BRANCH_CALLBACK(cx)    (onbranch = (cx)->branchCallback)    LOAD_BRANCH_CALLBACK(cx);    ok = JS_TRUE;#define CHECK_BRANCH(len)                                                     \    JS_BEGIN_MACRO                                                            \        if (len <= 0 && onbranch) {                                           \            SAVE_SP(fp);                                                      \            if (!(ok = (*onbranch)(cx, script)))                              \                goto out;                                                     \        }                                                                     \    JS_END_MACRO

⌨️ 快捷键说明

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