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

📄 jsiter.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (!obj)        return NULL;    /* Load and compute stack slot counts. */    argc = fp->argc;    nargs = JS_MAX(argc, fp->fun->nargs);    nvars = fp->nvars;    depth = fp->script->depth;    nslots = 2 + nargs + nvars + 2 * depth;    /* Allocate obj's private data struct. */    gen = (JSGenerator *)          JS_malloc(cx, sizeof(JSGenerator) + (nslots - 1) * sizeof(jsval));    if (!gen)        goto bad;    gen->obj = obj;    /* Steal away objects reflecting fp and point them at gen->frame. */    gen->frame.callobj = fp->callobj;    if (fp->callobj) {        JS_SetPrivate(cx, fp->callobj, &gen->frame);        fp->callobj = NULL;    }    gen->frame.argsobj = fp->argsobj;    if (fp->argsobj) {        JS_SetPrivate(cx, fp->argsobj, &gen->frame);        fp->argsobj = NULL;    }    /* These two references can be shared with fp until it goes away. */    gen->frame.varobj = fp->varobj;    gen->frame.thisp = fp->thisp;    /* Copy call-invariant script and function references. */    gen->frame.script = fp->script;    gen->frame.fun = fp->fun;    /* Use newsp to carve space out of gen->stack. */    newsp = gen->stack;    gen->arena.next = NULL;    gen->arena.base = (jsuword) newsp;    gen->arena.limit = gen->arena.avail = (jsuword) (newsp + nslots);#define COPY_STACK_ARRAY(vec,cnt,num)                                         \    JS_BEGIN_MACRO                                                            \        gen->frame.cnt = cnt;                                                 \        gen->frame.vec = newsp;                                               \        newsp += (num);                                                       \        memcpy(gen->frame.vec, fp->vec, (num) * sizeof(jsval));               \    JS_END_MACRO    /* Copy argv, rval, and vars. */    *newsp++ = fp->argv[-2];    *newsp++ = fp->argv[-1];    COPY_STACK_ARRAY(argv, argc, nargs);    gen->frame.rval = fp->rval;    COPY_STACK_ARRAY(vars, nvars, nvars);#undef COPY_STACK_ARRAY    /* Initialize or copy virtual machine state. */    gen->frame.down = NULL;    gen->frame.annotation = NULL;    gen->frame.scopeChain = fp->scopeChain;    gen->frame.pc = fp->pc;    /* Allocate generating pc and operand stack space. */    gen->frame.spbase = gen->frame.sp = newsp + depth;    /* Copy remaining state (XXX sharp* and xml* should be local vars). */    gen->frame.sharpDepth = 0;    gen->frame.sharpArray = NULL;    gen->frame.flags = fp->flags | JSFRAME_GENERATOR;    gen->frame.dormantNext = NULL;    gen->frame.xmlNamespace = NULL;    gen->frame.blockChain = NULL;    /* Note that gen is newborn. */    gen->state = JSGEN_NEWBORN;    if (!JS_SetPrivate(cx, obj, gen)) {        JS_free(cx, gen);        goto bad;    }    /*     * Register with GC to ensure that suspended finally blocks will be     * executed.     */    js_RegisterGenerator(cx, gen);    return obj;  bad:    cx->weakRoots.newborn[GCX_OBJECT] = NULL;    return NULL;}typedef enum JSGeneratorOp {    JSGENOP_NEXT,    JSGENOP_SEND,    JSGENOP_THROW,    JSGENOP_CLOSE} JSGeneratorOp;/* * Start newborn or restart yielding generator and perform the requested * operation inside its frame. */static JSBoolSendToGenerator(JSContext *cx, JSGeneratorOp op, JSObject *obj,                JSGenerator *gen, jsval arg, jsval *rval){    JSStackFrame *fp;    jsval junk;    JSArena *arena;    JSBool ok;    JS_ASSERT(gen->state ==  JSGEN_NEWBORN || gen->state == JSGEN_OPEN);    switch (op) {      case JSGENOP_NEXT:      case JSGENOP_SEND:        if (gen->state == JSGEN_OPEN) {            /*             * Store the argument to send as the result of the yield             * expression.             */            gen->frame.sp[-1] = arg;        }        gen->state = JSGEN_RUNNING;        break;      case JSGENOP_THROW:        JS_SetPendingException(cx, arg);        gen->state = JSGEN_RUNNING;        break;      default:        JS_ASSERT(op == JSGENOP_CLOSE);        JS_SetPendingException(cx, JSVAL_ARETURN);        gen->state = JSGEN_CLOSING;        break;    }    /* Extend the current stack pool with gen->arena. */    arena = cx->stackPool.current;    JS_ASSERT(!arena->next);    JS_ASSERT(!gen->arena.next);    JS_ASSERT(cx->stackPool.current != &gen->arena);    cx->stackPool.current = arena->next = &gen->arena;    /* Push gen->frame around the interpreter activation. */    fp = cx->fp;    cx->fp = &gen->frame;    gen->frame.down = fp;    ok = js_Interpret(cx, gen->frame.pc, &junk);    cx->fp = fp;    gen->frame.down = NULL;    /* Retract the stack pool and sanitize gen->arena. */    JS_ASSERT(!gen->arena.next);    JS_ASSERT(arena->next == &gen->arena);    JS_ASSERT(cx->stackPool.current == &gen->arena);    cx->stackPool.current = arena;    arena->next = NULL;    if (gen->frame.flags & JSFRAME_YIELDING) {        /* Yield cannot fail, throw or be called on closing. */        JS_ASSERT(ok);        JS_ASSERT(!cx->throwing);        JS_ASSERT(gen->state == JSGEN_RUNNING);        JS_ASSERT(op != JSGENOP_CLOSE);        gen->frame.flags &= ~JSFRAME_YIELDING;        gen->state = JSGEN_OPEN;        *rval = gen->frame.rval;        return JS_TRUE;    }    gen->state = JSGEN_CLOSED;    if (ok) {        /* Returned, explicitly or by falling off the end. */        if (op == JSGENOP_CLOSE)            return JS_TRUE;        return js_ThrowStopIteration(cx, obj);    }    /*     * An error, silent termination by branch callback or an exception.     * Propagate the condition to the caller.     */    return JS_FALSE;}/* * Execute gen's close hook after the GC detects that the object has become * unreachable. */JSBooljs_CloseGeneratorObject(JSContext *cx, JSGenerator *gen){    /* We pass null as rval since SendToGenerator never uses it with CLOSE. */    return SendToGenerator(cx, JSGENOP_CLOSE, gen->obj, gen, JSVAL_VOID, NULL);}/* * Common subroutine of generator_(next|send|throw|close) methods. */static JSBoolgenerator_op(JSContext *cx, JSGeneratorOp op,             JSObject *obj, uintN argc, jsval *argv, jsval *rval){    JSGenerator *gen;    JSString *str;    jsval arg;    if (!JS_InstanceOf(cx, obj, &js_GeneratorClass, argv))        return JS_FALSE;    gen = (JSGenerator *) JS_GetPrivate(cx, obj);    if (gen == NULL) {        /* This happens when obj is the generator prototype. See bug 352885. */        goto closed_generator;    }    switch (gen->state) {      case JSGEN_NEWBORN:        switch (op) {          case JSGENOP_NEXT:          case JSGENOP_THROW:            break;          case JSGENOP_SEND:            if (!JSVAL_IS_VOID(argv[0])) {                str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK,                                                 argv[0], NULL);                if (str) {                    JS_ReportErrorNumberUC(cx, js_GetErrorMessage, NULL,                                           JSMSG_BAD_GENERATOR_SEND,                                           JSSTRING_CHARS(str));                }                return JS_FALSE;            }            break;          default:            JS_ASSERT(op == JSGENOP_CLOSE);            gen->state = JSGEN_CLOSED;            return JS_TRUE;        }        break;      case JSGEN_OPEN:        break;      case JSGEN_RUNNING:      case JSGEN_CLOSING:        str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, argv[-1],                                         JS_GetFunctionId(gen->frame.fun));        if (str) {            JS_ReportErrorNumberUC(cx, js_GetErrorMessage, NULL,                                   JSMSG_NESTING_GENERATOR,                                   JSSTRING_CHARS(str));        }        return JS_FALSE;      default:        JS_ASSERT(gen->state == JSGEN_CLOSED);      closed_generator:        switch (op) {          case JSGENOP_NEXT:          case JSGENOP_SEND:            return js_ThrowStopIteration(cx, obj);          case JSGENOP_THROW:            JS_SetPendingException(cx, argv[0]);            return JS_FALSE;          default:            JS_ASSERT(op == JSGENOP_CLOSE);            return JS_TRUE;        }    }    arg = (op == JSGENOP_SEND || op == JSGENOP_THROW)          ? argv[0]          : JSVAL_VOID;    if (!SendToGenerator(cx, op, obj, gen, arg, rval))        return JS_FALSE;    return JS_TRUE;}static JSBoolgenerator_send(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,               jsval *rval){    return generator_op(cx, JSGENOP_SEND, obj, argc, argv, rval);}static JSBoolgenerator_next(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,               jsval *rval){    return generator_op(cx, JSGENOP_NEXT, obj, argc, argv, rval);}static JSBoolgenerator_throw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,                jsval *rval){    return generator_op(cx, JSGENOP_THROW, obj, argc, argv, rval);}static JSBoolgenerator_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,                jsval *rval){    return generator_op(cx, JSGENOP_CLOSE, obj, argc, argv, rval);}static JSFunctionSpec generator_methods[] = {    {js_iterator_str, iterator_self,     0,JSPROP_READONLY|JSPROP_PERMANENT,0},    {js_next_str,     generator_next,    0,JSPROP_READONLY|JSPROP_PERMANENT,0},    {js_send_str,     generator_send,    1,JSPROP_READONLY|JSPROP_PERMANENT,0},    {js_throw_str,    generator_throw,   1,JSPROP_READONLY|JSPROP_PERMANENT,0},    {js_close_str,    generator_close,   0,JSPROP_READONLY|JSPROP_PERMANENT,0},    {0,0,0,0,0}};#endif /* JS_HAS_GENERATORS */JSObject *js_InitIteratorClasses(JSContext *cx, JSObject *obj){    JSObject *proto, *stop;    /* Idempotency required: we initialize several things, possibly lazily. */    if (!js_GetClassObject(cx, obj, JSProto_StopIteration, &stop))        return NULL;    if (stop)        return stop;    proto = JS_InitClass(cx, obj, NULL, &js_IteratorClass, Iterator, 2,                         NULL, iterator_methods, NULL, NULL);    if (!proto)        return NULL;    proto->slots[JSSLOT_ITER_STATE] = JSVAL_NULL;#if JS_HAS_GENERATORS    /* Initialize the generator internals if configured. */    if (!JS_InitClass(cx, obj, NULL, &js_GeneratorClass, NULL, 0,                      NULL, generator_methods, NULL, NULL)) {        return NULL;    }#endif    return JS_InitClass(cx, obj, NULL, &js_StopIterationClass, NULL, 0,                        NULL, NULL, NULL, NULL);}

⌨️ 快捷键说明

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