Bug 771743 - Remove generator_op and have the methods that call it do their work manually. r=luke
authorJeff Walden <jwalden@mit.edu>
Fri, 06 Jul 2012 15:35:59 -0700
changeset 98901 dfab02971a0883d4cbe592405a00efc2440f25ef
parent 98900 7820ae26bd7f9a52c69c779c3b7287c20167e751
child 98902 092c73924711b95ff33a0b1506f08fbb8ec61932
push id11714
push userjwalden@mit.edu
push dateWed, 11 Jul 2012 00:31:31 +0000
treeherdermozilla-inbound@dfab02971a08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs771743
milestone16.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 771743 - Remove generator_op and have the methods that call it do their work manually. r=luke
js/src/jsiter.cpp
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -1593,102 +1593,132 @@ CloseGenerator(JSContext *cx, JSObject *
     }
 
     if (gen->state == JSGEN_CLOSED)
         return JS_TRUE;
 
     return SendToGenerator(cx, JSGENOP_CLOSE, obj, gen, UndefinedValue());
 }
 
-/*
- * Common subroutine of generator_(next|send|throw|close) methods.
- */
 static JSBool
-generator_op(JSContext *cx, Native native, JSGeneratorOp op, Value *vp, unsigned argc)
+generator_send(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     JSObject *thisObj;
-    if (!NonGenericMethodGuard(cx, args, native, &GeneratorClass, &thisObj))
+    if (!NonGenericMethodGuard(cx, args, generator_send, &GeneratorClass, &thisObj))
         return false;
     if (!thisObj)
         return true;
 
     JSGenerator *gen = (JSGenerator *) thisObj->getPrivate();
-    if (!gen) {
+    if (!gen || gen->state == JSGEN_CLOSED) {
         /* This happens when obj is the generator prototype. See bug 352885. */
-        goto closed_generator;
+        return js_ThrowStopIteration(cx);
+    }
+
+    if (gen->state == JSGEN_NEWBORN && args.hasDefined(0)) {
+        js_ReportValueError(cx, JSMSG_BAD_GENERATOR_SEND,
+                            JSDVG_SEARCH_STACK, args[0], NULL);
+        return false;
+    }
+
+    if (!SendToGenerator(cx, JSGENOP_SEND, thisObj, gen,
+                         args.length() > 0 ? args[0] : UndefinedValue()))
+    {
+        return false;
     }
 
-    if (gen->state == JSGEN_NEWBORN) {
-        switch (op) {
-          case JSGENOP_NEXT:
-          case JSGENOP_THROW:
-            break;
+    args.rval() = gen->fp->returnValue();
+    return true;
+
+}
 
-          case JSGENOP_SEND:
-            if (args.hasDefined(0)) {
-                js_ReportValueError(cx, JSMSG_BAD_GENERATOR_SEND,
-                                    JSDVG_SEARCH_STACK, args[0], NULL);
-                return false;
-            }
-            break;
+static JSBool
+generator_next(JSContext *cx, unsigned argc, Value *vp)
+{
+    CallArgs args = CallArgsFromVp(argc, vp);
 
-          default:
-            JS_ASSERT(op == JSGENOP_CLOSE);
-            SetGeneratorClosed(cx, gen);
-            args.rval().setUndefined();
-            return true;
-        }
-    } else if (gen->state == JSGEN_CLOSED) {
-      closed_generator:
-        switch (op) {
-          case JSGENOP_NEXT:
-          case JSGENOP_SEND:
-            return js_ThrowStopIteration(cx);
-          case JSGENOP_THROW:
-            cx->setPendingException(args.length() >= 1 ? args[0] : UndefinedValue());
-            return false;
-          default:
-            JS_ASSERT(op == JSGENOP_CLOSE);
-            args.rval().setUndefined();
-            return true;
-        }
+    JSObject *thisObj;
+    if (!NonGenericMethodGuard(cx, args, generator_next, &GeneratorClass, &thisObj))
+        return false;
+    if (!thisObj)
+        return true;
+
+    JSGenerator *gen = (JSGenerator *) thisObj->getPrivate();
+    if (!gen || gen->state == JSGEN_CLOSED) {
+        /* This happens when obj is the generator prototype. See bug 352885. */
+        return js_ThrowStopIteration(cx);
     }
 
-    bool undef = ((op == JSGENOP_SEND || op == JSGENOP_THROW) && args.length() != 0);
-    if (!SendToGenerator(cx, op, thisObj, gen, undef ? args[0] : UndefinedValue()))
+    if (!SendToGenerator(cx, JSGENOP_NEXT, thisObj, gen, UndefinedValue()))
         return false;
 
     args.rval() = gen->fp->returnValue();
     return true;
 }
 
 static JSBool
-generator_send(JSContext *cx, unsigned argc, Value *vp)
-{
-    return generator_op(cx, generator_send, JSGENOP_SEND, vp, argc);
-}
-
-static JSBool
-generator_next(JSContext *cx, unsigned argc, Value *vp)
-{
-    return generator_op(cx, generator_next, JSGENOP_NEXT, vp, argc);
-}
-
-static JSBool
 generator_throw(JSContext *cx, unsigned argc, Value *vp)
 {
-    return generator_op(cx, generator_throw, JSGENOP_THROW, vp, argc);
+    CallArgs args = CallArgsFromVp(argc, vp);
+
+    JSObject *thisObj;
+    if (!NonGenericMethodGuard(cx, args, generator_throw, &GeneratorClass, &thisObj))
+        return false;
+    if (!thisObj)
+        return true;
+
+    JSGenerator *gen = (JSGenerator *) thisObj->getPrivate();
+    if (!gen || gen->state == JSGEN_CLOSED) {
+        /* This happens when obj is the generator prototype. See bug 352885. */
+        cx->setPendingException(args.length() >= 1 ? args[0] : UndefinedValue());
+        return false;
+    }
+
+    if (!SendToGenerator(cx, JSGENOP_THROW, thisObj, gen,
+                         args.length() > 0 ? args[0] : UndefinedValue()))
+    {
+        return false;
+    }
+
+    args.rval() = gen->fp->returnValue();
+    return true;
+
 }
 
 static JSBool
 generator_close(JSContext *cx, unsigned argc, Value *vp)
 {
-    return generator_op(cx, generator_close, JSGENOP_CLOSE, vp, argc);
+    CallArgs args = CallArgsFromVp(argc, vp);
+
+    JSObject *thisObj;
+    if (!NonGenericMethodGuard(cx, args, generator_close, &GeneratorClass, &thisObj))
+        return false;
+    if (!thisObj)
+        return true;
+
+    JSGenerator *gen = (JSGenerator *) thisObj->getPrivate();
+    if (!gen || gen->state == JSGEN_CLOSED) {
+        /* This happens when obj is the generator prototype. See bug 352885. */
+        args.rval().setUndefined();
+        return true;
+    }
+
+    if (gen->state == JSGEN_NEWBORN) {
+        SetGeneratorClosed(cx, gen);
+        args.rval().setUndefined();
+        return true;
+    }
+
+    if (!SendToGenerator(cx, JSGENOP_CLOSE, thisObj, gen, UndefinedValue()))
+        return false;
+
+    args.rval() = gen->fp->returnValue();
+    return true;
 }
 
 static JSFunctionSpec generator_methods[] = {
     JS_FN(js_next_str,      generator_next,     0,JSPROP_ROPERM),
     JS_FN(js_send_str,      generator_send,     1,JSPROP_ROPERM),
     JS_FN(js_throw_str,     generator_throw,    1,JSPROP_ROPERM),
     JS_FN(js_close_str,     generator_close,    0,JSPROP_ROPERM),
     JS_FS_END