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

Prevent infinite loops in lazily defined props #10879

Conversation

vladimir-kotikov
Copy link
Contributor

@vladimir-kotikov vladimir-kotikov commented Nov 11, 2016

This prevents another kind of infinite loop in props with lazy getters, when real getter might try to access original property thus triggering getValue again.

This is specifically the case 'regenerator-runtime', which happens only under some specific conditions (i.e. running in NodeJS inside vm context, see microsoft/vscode-react-native#340 for additional details)

This prevents another kind of infinite loop in props with lazy getters, when real getter might try to access original property thus making it trigger `getValue` again.

This is specifically the case 'regenerator-runtime', which happens only under some specific conditions (i.e. running in NodeJS inside `vm` context)
@facebook-github-bot
Copy link
Contributor

By analyzing the blame information on this pull request, we identified @yungsters to be a potential reviewer.

@vladimir-kotikov
Copy link
Contributor Author

/cc @MSLaguana

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Nov 11, 2016
// This is specifically the case with 'regenerator-runtime' module, which
// checks if `global.regeneratorRuntime` property is already defined and
// thus triggers `getValue()` again.
valueSet = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems dangerous to set in the general case. It may work because Regenerator is written in a specific way but I don't think it's a good idea to mark the value as set when it hasn't been.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why it's dangerous? The getter is synchronous and nobody can access property's value from outside until get() call is completed. It's only possible to access it from 'inside', i.e. recursively, but in this case we'd get an infinite recursion, which we need to stop.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's dangerous in the recursive case because the recursively called code probably doesn't expect to receive undefined when it's called re-entrantly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So basically you suggest fixing this in regenerator? I'm fine with that, but i think this rings a bell. Honestly, I don't know whether it should be expected or not but I'd say that we should do something to stop recursion, because nobody can guarantee that at some moment we won't run into the same situation again.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing this in Regenerator is probably the best solution.

we should do something to stop recursion

Sure, the best solution I can think of is to throw an error with a clear message explaining which property was recursively accessed.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that this particular issue is caused by regenerator though. When I saw this myself, it was actually the line https://github.com/facebook/react-native/blob/master/Libraries/Core/InitializeCore.js#L156 which caused the recursion: The access of global.regneratorRuntime called into the same getter function.

Copy link
Contributor Author

@vladimir-kotikov vladimir-kotikov Nov 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MSLaguana, you're right - I revisited this again and it looks like it doesn't related to regenerator - I can confirm that the loop starts in getter itself, not in regenerator.

Some experiments show that our problem has to do with Node - in particular it's very possible that we're getting into loop because delete global.regeneratorRuntime doesn't actually delete anything

image

When we're running this code in Chrome, after property deletion calling global.regeneratorRuntime doesn't trigger getter again because the property been deleted.

I think it's very likely that we're running into nodejs/node#6287 - not sure how to deal with this though

@vladimir-kotikov
Copy link
Contributor Author

Closing this, as it doesn't seem to be the right solution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants