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

📄 jsiter.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 3 页
字号:
                          JSITER_KEYVALUE)));    /* JSITER_KEYVALUE must always come with JSITER_FOREACH */    JS_ASSERT(!(flags & JSITER_KEYVALUE) || (flags & JSITER_FOREACH));    /* XXX work around old valueOf call hidden beneath js_ValueToObject */    if (!JSVAL_IS_PRIMITIVE(*vp)) {        obj = JSVAL_TO_OBJECT(*vp);    } else {        /*         * Enumerating over null and undefined gives an empty enumerator.         * This is contrary to ECMA-262 9.9 ToObject, invoked from step 3 of         * the first production in 12.6.4 and step 4 of the second production,         * but it's "web JS" compatible.         */        if ((flags & JSITER_ENUMERATE)) {            if (!js_ValueToObject(cx, *vp, &obj))                return JS_FALSE;            if (!obj)                goto default_iter;        } else {            obj = js_ValueToNonNullObject(cx, *vp);            if (!obj)                return JS_FALSE;        }    }    JS_ASSERT(obj);    JS_PUSH_TEMP_ROOT_OBJECT(cx, obj, &tvr);    atom = cx->runtime->atomState.iteratorAtom;#if JS_HAS_XML_SUPPORT    if (OBJECT_IS_XML(cx, obj)) {        if (!js_GetXMLFunction(cx, obj, ATOM_TO_JSID(atom), vp))            goto bad;    } else#endif    {        if (!OBJ_GET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp))            goto bad;    }    if (JSVAL_IS_VOID(*vp)) {      default_iter:        /*         * Fail over to the default enumerating native iterator.         *         * Create iterobj with a NULL parent to ensure that we use the correct         * scope chain to lookup the iterator's constructor. Since we use the         * parent slot to keep track of the iterable, we must fix it up after.         */        iterobj = js_NewObject(cx, &js_IteratorClass, NULL, NULL);        if (!iterobj)            goto bad;        /* Store iterobj in *vp to protect it from GC (callers must root vp). */        *vp = OBJECT_TO_JSVAL(iterobj);        if (!InitNativeIterator(cx, iterobj, obj, flags))            goto bad;    } else {        arg = BOOLEAN_TO_JSVAL((flags & JSITER_FOREACH) == 0);        if (!js_InternalInvoke(cx, obj, *vp, JSINVOKE_ITERATOR, 1, &arg, vp))            goto bad;        if (JSVAL_IS_PRIMITIVE(*vp)) {            str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, *vp, NULL);            if (str) {                JS_ReportErrorNumberUC(cx, js_GetErrorMessage, NULL,                                       JSMSG_BAD_ITERATOR_RETURN,                                       JSSTRING_CHARS(str),                                       JSSTRING_CHARS(ATOM_TO_STRING(atom)));            }            goto bad;        }    }    ok = JS_TRUE;  out:    if (obj)        JS_POP_TEMP_ROOT(cx, &tvr);    return ok;  bad:    ok = JS_FALSE;    goto out;}static JSBoolCallEnumeratorNext(JSContext *cx, JSObject *iterobj, uintN flags, jsval *rval){    JSObject *obj, *origobj;    jsval state;    JSBool foreach;    jsid id;    JSObject *obj2;    JSBool cond;    JSClass *clasp;    JSExtendedClass *xclasp;    JSProperty *prop;    JSString *str;    JS_ASSERT(flags & JSITER_ENUMERATE);    JS_ASSERT(JSVAL_TO_PRIVATE(iterobj->slots[JSSLOT_CLASS]) ==              &js_IteratorClass);    obj = JSVAL_TO_OBJECT(iterobj->slots[JSSLOT_PARENT]);    origobj = JSVAL_TO_OBJECT(iterobj->slots[JSSLOT_PROTO]);    state = iterobj->slots[JSSLOT_ITER_STATE];    if (JSVAL_IS_NULL(state))        goto stop;    foreach = (flags & JSITER_FOREACH) != 0;#if JS_HAS_XML_SUPPORT    /*     * Treat an XML object specially only when it starts the prototype chain.     * Otherwise we need to do the usual deleted and shadowed property checks.     */    if (obj == origobj && OBJECT_IS_XML(cx, obj)) {        if (foreach) {            JSXMLObjectOps *xmlops = (JSXMLObjectOps *) obj->map->ops;            if (!xmlops->enumerateValues(cx, obj, JSENUMERATE_NEXT, &state,                                         &id, rval)) {                return JS_FALSE;            }        } else {            if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_NEXT, &state, &id))                return JS_FALSE;        }        iterobj->slots[JSSLOT_ITER_STATE] = state;        if (JSVAL_IS_NULL(state))            goto stop;    } else#endif    {      restart:        if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_NEXT, &state, &id))            return JS_TRUE;        iterobj->slots[JSSLOT_ITER_STATE] = state;        if (JSVAL_IS_NULL(state)) {#if JS_HAS_XML_SUPPORT            if (OBJECT_IS_XML(cx, obj)) {                /*                 * We just finished enumerating an XML obj that is present on                 * the prototype chain of a non-XML origobj. Stop further                 * prototype chain searches because XML objects don't                 * enumerate prototypes.                 */                JS_ASSERT(origobj != obj);                JS_ASSERT(!OBJECT_IS_XML(cx, origobj));            } else#endif            {                obj = OBJ_GET_PROTO(cx, obj);                if (obj) {                    iterobj->slots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(obj);                    if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &state, NULL))                        return JS_FALSE;                    iterobj->slots[JSSLOT_ITER_STATE] = state;                    if (!JSVAL_IS_NULL(state))                        goto restart;                }            }            goto stop;        }        /* Skip properties not in obj when looking from origobj. */        if (!OBJ_LOOKUP_PROPERTY(cx, origobj, id, &obj2, &prop))            return JS_FALSE;        if (!prop)            goto restart;        OBJ_DROP_PROPERTY(cx, obj2, prop);        /*         * If the id was found in a prototype object or an unrelated object         * (specifically, not in an inner object for obj), skip it. This step         * means that all OBJ_LOOKUP_PROPERTY implementations must return an         * object further along on the prototype chain, or else possibly an         * object returned by the JSExtendedClass.outerObject optional hook.         */        if (obj != obj2) {            cond = JS_FALSE;            clasp = OBJ_GET_CLASS(cx, obj2);            if (clasp->flags & JSCLASS_IS_EXTENDED) {                xclasp = (JSExtendedClass *) clasp;                cond = xclasp->outerObject &&                    xclasp->outerObject(cx, obj2) == obj;            }            if (!cond)                goto restart;        }        if (foreach) {            /* Get property querying the original object. */            if (!OBJ_GET_PROPERTY(cx, origobj, id, rval))                return JS_FALSE;        }    }    if (foreach) {        if (flags & JSITER_KEYVALUE) {            if (!NewKeyValuePair(cx, id, *rval, rval))                return JS_FALSE;        }    } else {        /* Make rval a string for uniformity and compatibility. */        if (JSID_IS_ATOM(id)) {            *rval = ATOM_KEY(JSID_TO_ATOM(id));        }#if JS_HAS_XML_SUPPORT        else if (JSID_IS_OBJECT(id)) {            str = js_ValueToString(cx, OBJECT_JSID_TO_JSVAL(id));            if (!str)                return JS_FALSE;            *rval = STRING_TO_JSVAL(str);        }#endif        else {            str = js_NumberToString(cx, (jsdouble)JSID_TO_INT(id));            if (!str)                return JS_FALSE;            *rval = STRING_TO_JSVAL(str);        }    }    return JS_TRUE;  stop:    JS_ASSERT(iterobj->slots[JSSLOT_ITER_STATE] == JSVAL_NULL);    *rval = JSVAL_HOLE;    return JS_TRUE;}JSBooljs_CallIteratorNext(JSContext *cx, JSObject *iterobj, jsval *rval){    uintN flags;    /* Fast path for native iterators */    if (OBJ_GET_CLASS(cx, iterobj) == &js_IteratorClass) {        flags = JSVAL_TO_INT(OBJ_GET_SLOT(cx, iterobj, JSSLOT_ITER_FLAGS));        if (flags & JSITER_ENUMERATE)            return CallEnumeratorNext(cx, iterobj, flags, rval);        /*         * Call next directly as all the methods of the native iterator are         * read-only and permanent.         */        if (!IteratorNextImpl(cx, iterobj, rval))            return JS_FALSE;    } else {        jsid id = ATOM_TO_JSID(cx->runtime->atomState.nextAtom);        if (!JS_GetMethodById(cx, iterobj, id, &iterobj, rval))            return JS_FALSE;        if (!js_InternalCall(cx, iterobj, *rval, 0, NULL, rval)) {            /* Check for StopIteration. */            if (!cx->throwing ||                JSVAL_IS_PRIMITIVE(cx->exception) ||                OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(cx->exception))                    != &js_StopIterationClass) {                return JS_FALSE;            }            /* Inline JS_ClearPendingException(cx). */            cx->throwing = JS_FALSE;            cx->exception = JSVAL_VOID;            *rval = JSVAL_HOLE;            return JS_TRUE;        }    }    return JS_TRUE;}static JSBoolstopiter_hasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp){    *bp = !JSVAL_IS_PRIMITIVE(v) &&          OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_StopIterationClass;    return JS_TRUE;}JSClass js_StopIterationClass = {    js_StopIteration_str,    JSCLASS_HAS_CACHED_PROTO(JSProto_StopIteration),    JS_PropertyStub,  JS_PropertyStub,    JS_PropertyStub,  JS_PropertyStub,    JS_EnumerateStub, JS_ResolveStub,    JS_ConvertStub,   JS_FinalizeStub,    NULL,             NULL,    NULL,             NULL,    NULL,             stopiter_hasInstance,    NULL,             NULL};#if JS_HAS_GENERATORSstatic voidgenerator_finalize(JSContext *cx, JSObject *obj){    JSGenerator *gen;    gen = (JSGenerator *) JS_GetPrivate(cx, obj);    if (gen) {        /*         * gen can be open on shutdown when close hooks are ignored or when         * the embedding cancels scheduled close hooks.         */        JS_ASSERT(gen->state == JSGEN_NEWBORN || gen->state == JSGEN_CLOSED ||                  gen->state == JSGEN_OPEN);        JS_free(cx, gen);    }}static uint32generator_mark(JSContext *cx, JSObject *obj, void *arg){    JSGenerator *gen;    gen = (JSGenerator *) JS_GetPrivate(cx, obj);    if (gen) {        /*         * We must mark argv[-2], as js_MarkStackFrame will not.  Note that         * js_MarkStackFrame will mark thisp (argv[-1]) and actual arguments,         * plus any missing formals and local GC roots.         */        JS_ASSERT(!JSVAL_IS_PRIMITIVE(gen->frame.argv[-2]));        GC_MARK(cx, JSVAL_TO_GCTHING(gen->frame.argv[-2]), "generator");        js_MarkStackFrame(cx, &gen->frame);    }    return 0;}JSClass js_GeneratorClass = {    js_Generator_str,    JSCLASS_HAS_PRIVATE | JSCLASS_IS_ANONYMOUS |    JSCLASS_HAS_CACHED_PROTO(JSProto_Generator),    JS_PropertyStub,  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,    JS_EnumerateStub, JS_ResolveStub,  JS_ConvertStub,  generator_finalize,    NULL,             NULL,            NULL,            NULL,    NULL,             NULL,            generator_mark,  NULL};/* * Called from the JSOP_GENERATOR case in the interpreter, with fp referring * to the frame by which the generator function was activated.  Create a new * JSGenerator object, which contains its own JSStackFrame that we populate * from *fp.  We know that upon return, the JSOP_GENERATOR opcode will return * from the activation in fp, so we can steal away fp->callobj and fp->argsobj * if they are non-null. */JSObject *js_NewGenerator(JSContext *cx, JSStackFrame *fp){    JSObject *obj;    uintN argc, nargs, nvars, depth, nslots;    JSGenerator *gen;    jsval *newsp;    /* After the following return, failing control flow must goto bad. */    obj = js_NewObject(cx, &js_GeneratorClass, NULL, NULL);

⌨️ 快捷键说明

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