-
Notifications
You must be signed in to change notification settings - Fork 864
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
Fixed problems with hoisting #1806
Conversation
Co-authored-by: Andrea Bergia <[email protected]>
Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function#block-level_function_declaration, I don't think any assumptions are to be made as to whether functions declarations within blocks are hoisted or not, at least in non-strict mode. When in Strict mode however, the function should be hoisted, but only to the top of it's containing block, so not the outer function Also see related PR/discussion #970 |
We discovered this because of a problem reported by one of our customers. What we implemented is coherent with the other engines that we have tested (v8, jsc, spidermonkey, quickjs) from what we can tell. Functions declared inside blocks are not hoisted to the top of the function; the equivalent Example: if (typeof 'print' === 'undefined') {
print = console.log.bind(console);
}
(function test() {
print(typeof inner);
if (true) {
print(typeof inner);
function inner() {}
}
})(); This prints: |
I'm all for doing it. I wonder why there aren't any test262 tests that fail because of this behavior, though. Are there other tests we can pull from the V8 test suite (We have also used the "mjsunit" tests from the V8 repo somewhere) so that we can make sure that we're not off on our own here? Otherwise I think this is a good change! |
This looks fine to me. Thanks for doing it! |
Sorry, didn't get around to check that. |
Same here but at least there was a test in HtmlUnit/core-js and also a fix for that. Have removed our fix and all the tests are still passing. Thanks @andreabergia for all your work (hope for more) |
This PR fixes some problems with function hoisting in nested scopes. Consider this:
The hoisting rules say that this is sorta equivalent to:
Rhino correctly handles hoisting at the top level of the function (i.e. for
inner
), but it does not handle it correctly for nested blocks (i.e. forinBlock
). So in the example above, the following exception gets thrown:This PR fixes the problem. The trick is that, whenever the IR for a block is generated, nested functions are hoisted on top of it.