Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yielded values stomp on each other from regenerator. #2385

Closed
tolmasky opened this issue Sep 15, 2015 · 3 comments
Closed

Yielded values stomp on each other from regenerator. #2385

tolmasky opened this issue Sep 15, 2015 · 3 comments
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue

Comments

@tolmasky
Copy link
Contributor

If we look at the example below:

var x = function *generator()
{
    (yield 1)(yield 2)
}

i = x()

console.log(i.next().value);
console.log(i.next(console.log).value);
console.log(i.next(3).value);

In node v0.12 (using real generators), the result is:

1
2
3
undefined

However, under babel, the result is:

1
2

/Users/tolmasky/.nvm/v0.10.39/lib/node_modules/babel/node_modules/babel-core/node_modules/regenerator/runtime.js:505
        throw exception;
              ^
TypeError: number is not a function

To take a deeper look, we can use two functions:

var x = function *generator()
{
    (f1 = yield 1)(f2 = yield 2)

    console.log(f1 + " " + f2);
}

i = x()

i.next();
i.next(function f1() { });
i.next(function f2() { });

We'd expect:

function f1() {} function f2() {}

But instead get:

function f2() {} function f2() {}

The second value stomps on the old.

@tolmasky
Copy link
Contributor Author

Just from looking at the generated code, it appears that with this type of expression a combined switch step is produced:

var x = regeneratorRuntime.mark(function generator() {
    return regeneratorRuntime.wrap(function generator$(context$1$0) {
        while (1) switch (context$1$0.prev = context$1$0.next) {
            case 0:
                context$1$0.next = 2;
                return 1;

            case 2:
                context$1$0.next = 4;
                return 2;

            case 4:
                context$1$0.t0 = f2 = context$1$0.sent;
                (f1 = context$1$0.sent)(context$1$0.t0);

                console.log(f1 + " " + f2);

            case 7:
            case "end":
                return context$1$0.stop();
        }
    }, generator, this);
});

Compare to what happens if you just change it to (f1 = yield 1) + (f2 = yield 2) (another pexression with two yields):

var x = regeneratorRuntime.mark(function generator() {
    return regeneratorRuntime.wrap(function generator$(context$1$0) {
        while (1) switch (context$1$0.prev = context$1$0.next) {
            case 0:
                context$1$0.next = 2;
                return 1;

            case 2:
                context$1$0.t0 = f1 = context$1$0.sent;
                context$1$0.next = 5;
                return 2;

            case 5:
                context$1$0.t1 = f2 = context$1$0.sent;
                context$1$0.t0 + context$1$0.t1;

                console.log(f1 + " " + f2);

            case 8:
            case "end":
                return context$1$0.stop();
        }
    }, generator, this);
});

@sebmck
Copy link
Contributor

sebmck commented Sep 28, 2015

Moving to facebook/regenerator#218.

@benjamn
Copy link
Contributor

benjamn commented Dec 1, 2016

Per facebook/regenerator#218 (comment), this will be fixed when #4881 is merged.

@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label May 6, 2018
@lock lock bot locked as resolved and limited conversation to collaborators May 6, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue
Projects
None yet
Development

No branches or pull requests

3 participants