jsinterp.c

来自「java script test programing source code」· C语言 代码 · 共 1,863 行 · 第 1/5 页

C
1,863
字号
    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){    int stackDummy;    /*     * js_InternalInvoke could result in another try to get or set the same id     * again, see bug 355497.     */    if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                             JSMSG_OVER_RECURSED);        return JS_FALSE;    }    /*     * 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 &&        VALUE_IS_FUNCTION(cx, fval) &&        FUN_INTERPRETED((JSFunction *)                        JS_GetPrivate(cx, JSVAL_TO_OBJECT(fval))) &&        !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 flags, jsval *result){    JSInterpreterHook hook;    void *hookData, *mark;    JSStackFrame *oldfp, frame;    JSObject *obj, *tmp;    JSBool ok;    hook = cx->runtime->executeHook;    hookData = mark = NULL;    oldfp = cx->fp;    frame.script = script;    if (down) {        /* Propagate arg/var state for eval and the debugger API. */        frame.callobj = down->callobj;        frame.argsobj = down->argsobj;        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 {        frame.callobj = frame.argsobj = NULL;        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 = 0;        frame.argv = NULL;        frame.nvars = script->numGlobalVars;        if (frame.nvars) {            frame.vars = js_AllocRawStack(cx, frame.nvars, &mark);            if (!frame.vars)                return JS_FALSE;            memset(frame.vars, 0, frame.nvars * sizeof(jsval));        } else {            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.sharpDepth = 0;    frame.flags = flags;    frame.dormantNext = NULL;    frame.xmlNamespace = NULL;    frame.blockChain = 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, script->code, &frame.rval);    *result = frame.rval;    if (hookData) {        hook = cx->runtime->executeHook;        if (hook)            hook(cx, &frame, JS_FALSE, &ok, hookData);    }    if (mark)        js_FreeRawStack(cx, mark);    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;    jsint 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 (VALUE_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 |                                               JSPROP_GETTER |                                               JSPROP_SETTER),                                     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,                      JSObject **objp, JSProperty **propp){    JSObject *obj2;    JSProperty *prop;    uintN oldAttrs, report;    JSBool isFunction;    jsval value;    const char *type, *name;    if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))        return JS_FALSE;    if (propp) {        *objp = obj2;        *propp = prop;    }    if (!prop)        return JS_TRUE;    /*     * Use prop as a speedup hint to OBJ_GET_ATTRIBUTES, but drop it on error.     * An assertion at label bad: will insist that it is null.     */    if (!OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &oldAttrs)) {        OBJ_DROP_PROPERTY(cx, obj2, prop);#ifdef DEBUG        prop = NULL;#endif        goto bad;    }    /*     * From here, return true, or else goto bad on failure to null out params.     * If our caller doesn't want prop, drop it (we don't need it any longer).     */    if (!propp) {        OBJ_DROP_PROPERTY(cx, obj2, prop);        prop = NULL;    }    /* 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))            goto bad;        isFunction = VALUE_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, JSID_TO_ATOM(id));    if (!name)        goto bad;    return JS_ReportErrorFlagsAndNumber(cx, report,                                        js_GetErrorMessage, NULL,                                        JSMSG_REDECLARED_VAR,                                        type, name);bad:    if (propp) {        *objp = NULL;        *propp = NULL;    }    JS_ASSERT(!prop);    return JS_FALSE;}JSBooljs_StrictlyEqual(jsval lval, jsval rval){    jsval ltag = JSVAL_TAG(lval), rt

⌨️ 快捷键说明

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