Yep, thanks Brendan,<br><br>I filed the bug <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=641436">https://bugzilla.mozilla.org/show_bug.cgi?id=641436</a><br><br>But the thing with `this` is still interesting for me. So in this particular case `this` should be set to `undefined`. Should it be always set to `undefined` (strict) / global object and regardless -- calling from `new` or via simple call? There nothing is said about `this` value of the [[ExecutionContext]] created for the "newbord" generator. What should it be set to?<br>
<br>Thanks,<br>Dmitry.<br><br><div class="gmail_quote">On Sun, Mar 13, 2011 at 11:39 PM, Brendan Eich <span dir="ltr"><<a href="mailto:brendan@mozilla.com">brendan@mozilla.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div style="word-wrap: break-word;">Hi Dmitry,<div><br></div><div>It looks to me like you've just found a bug in SpiderMonkey's generator implementation, which pre-dates the strawman:generators proposal by four+ years. Please file it in the right place: <a href="https://bugzilla.mozilla.org/" target="_blank">https://bugzilla.mozilla.org/</a>. Thanks.</div>
<div><br></div><div>The bug is a regression. Here's what my Firefox 3-era JS shell does:</div><div><br></div><div><div>js> // infinite objects generator</div><div>js> let g = new function () {</div><div class="im">
<div>  this.x = 10;</div><div>  while (true) {</div><div>    yield;</div><div>  }</div><div>};</div></div><div>js> </div><div>js> // generate an array of 3 objects</div><div>js> let objects = [1, 2, 3].map(function(i) g.next());</div>
<div>js> objects</div><div>,,</div><div>js> uneval(objects)</div><div>[(void 0), (void 0), (void 0)]</div></div><div><br></div><div>Clearly, yield; should not yield a mysterious object as the return value of g.next().</div>
<div><br></div><div>/be</div><div><br><div><div><div></div><div class="h5"><div>On Mar 13, 2011, at 3:04 PM, Dmitry A. Soshnikov wrote:</div><br></div></div><blockquote type="cite"><div><div></div><div class="h5">
<div text="#000000" bgcolor="#ffffff">
    Hello,<br>
    <br>
    I hope you can help with explaining of what is going on with `this`
    value inside the body of a generator?<br>
    <br>
    Consider e.g. the following case:<br>
    <br>
    // infinite objects generator<br>
    let g = new function () {<br>
      this.x = 10;<br>
      while (true) {<br>
        yield;<br>
      }<br>
    };<br>
    <br>
    // generate an array of 3 objects<br>
    let objects = [1, 2, 3].map(function(i) g.next());<br>
    <br>
    console.dir(objects);<br>
    <br>
    Results:<br>
    <br>
    [<br>
        [[Class]]: "Array",<br>
        length: 3,<br>
        0: {<br>
            [[Class]]: "Object",<br>
            x: 10<br>
        },<br>
        1: {<br>
            [[Class]]: "Object"<br>
        },<br>
        2: {<br>
            [[Class]]: "Object"<br>
        }<br>
    ]<br>
    <br>
    Only first object has `x` property. Also:<br>
    <br>
    console.log(objects[0] == objects[1]); // false<br>
    console.log(objects[1] == objects[2]); // false<br>
    <br>
    <br>
    <br>
    As I understand, [[Construct]] activated by the `new` calls [[Call]]
    of the function, which produces the `g` generator. I look here:
    <a href="http://wiki.ecmascript.org/doku.php?id=strawman:generators" target="_blank">http://wiki.ecmascript.org/doku.php?id=strawman:generators</a> and see:<br>
    <br>
    <h2>Calling</h2>
    <div><p> Let <code>f</code> be a generator function. The semantics of
        a function call <code>f(x1, ..., xn)</code> is:
      </p><p>
            Let E = a new VariableEnvironment record with mappings for <code>x1</code>
        ... <code>xn</code> <br>
            Let S = the current scope chain extended with E <br>
            Let V = a new generator object with <br>
                [[Scope]] = S <br>
                [[Code]] = f.[[Code]] <br>
                [[ExecutionContext]] = <b>null</b> <br>
                [[State]] = “newborn” <br>
                [[Handler]] = the standard generator handler <br>
            Return V
      </p>
    </div>
    <br>
    So, `g` will be the generator with the needed [[Code]] and empty
    [[ExecutionContext]]. Notice, there nothing is said about `this`
    value.<br>
    <br>
    In calling `next` (i.e. `send(undefined)`) we get into:<br>
    <br>
    <h2>Internal method: send</h2>
    <div><p> G.[[Send]]
      </p><p>
            Let State = G.[[State]] <br>
            If State = “executing” Throw Error <br>
            If State = “closed” Throw Error <br>
            Let X be the first argument <br>
            If State = “newborn” <br>
                If X != <b>undefined</b> Throw TypeError <br>
                Let K = <font color="#ff0000">a new execution context
          as for a function call </font><br>
                K.currentGenerator := G <br>
                K.scopeChain := G.[[Scope]] <br>
                Push K onto the stack <br>
                Return <i>Execute</i>(G.[[Code]]) <br>
            G.[[State]] := “executing” <br>
            Let Result = <i>Resume</i>(G.[[ExecutionContext]], <b>normal</b>,
        X) <br>
            Return Result
      </p>
    </div>
    We see that a new context is created but again, nothing is said
    about its `this` value.<br>
    <br>
    When evaluating <i>Execute</i>(G.[[Code]]) we with yield get
    into:<br>
    <br>
    <h2>Yielding</h2>
    <div><p> The semantics of evaluating an expression of the form <code>yield
          e</code> is:
      </p><p>
            Let V ?= Evaluate(e) <br>
            Let K = <font color="#ff0000">the current execution context
        </font><br>
            Let O = K.currentGenerator <br>
            O.[[ExecutionContext]] := K <br>
            O.[[State]] := “suspended” <br>
            Pop the current execution context <br>
            Return (<b>normal</b>, V, <b>null</b>)
      </p>
    </div>
    <br>
    Btw, what does "?=" mean?<br>
    <br>
    Here the K is the context created on in the `send` method (still we
    haven't any info about `this` value).<br>
    <br>
    The following call to `next` will again enter `send` method with
    `undefined` but we already get into:<br>
    <br>
    <h2>Resuming generators</h2>
    <div><p> <b>Operation</b> <i>Resume</i>(K,
        completionType, V)
      </p><p>
            Push K onto the execution context stack <br>
            Let G = K.currentGenerator <br>
            Set the current scope chain to G.[[Scope]] <br>
            Continue executing K as if its last expression produced
        (completionType, V, <b>null</b>)
      </p>
    </div>
    where we proceed with evaluating previously saved continuation. And
    again, nothing about `this` is said.<br>
    <br>
    As I see, during all these steps always the same K is passed around
    and evaluated. `This` value is a property of the context and K has
    it, but which?<br>
    <br>
    As was shown in the example above, `this` is set to the newly
    created object, but it's a current SpiderMonkey's behavior; don't
    know how it correlate with this draft spec.<br>
    <br>
    Consider e.g. the following example (tested in SpiderMonkey):<br>
    <br>
    g = new function() {<br>
      yield new Boolean((yield) == this)<br>
    };<br>
    <br>
    console.log(''+ g.send(g.next())); // false<br>
    <br>
    g = new function() {<br>
      yield new Boolean(this == (yield))<br>
    };<br>
    <br>
    console.log(''+ g.send(g.next())); // true <br>
    <br>
    Why in first call `yield` wasn't newly created object and in the
    second one -- it was? What actually _should_ yield without an
    argument yields? `undefined` I guess.<br>
    <br>
    So don't know which behavior is correct and whether it's a strange
    behavior in current SpiderMonkey.<br>
    <br>
    Thanks,<br>
    Dmitry.<br>
  </div></div></div>

_______________________________________________<br>es-discuss mailing list<br><a href="mailto:es-discuss@mozilla.org" target="_blank">es-discuss@mozilla.org</a><br><a href="https://mail.mozilla.org/listinfo/es-discuss" target="_blank">https://mail.mozilla.org/listinfo/es-discuss</a><br>
</blockquote></div><br></div></div></blockquote></div><br>