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

Block scope not being used on variable allocation #39

Closed
jasonwilliams opened this issue Jun 30, 2019 · 0 comments · Fixed by #173
Closed

Block scope not being used on variable allocation #39

jasonwilliams opened this issue Jun 30, 2019 · 0 comments · Fixed by #173
Labels
Hacktoberfest Hacktoberfest 2021 - https://hacktoberfest.digitalocean.com

Comments

@jasonwilliams
Copy link
Member

When we step into a new function, we create a new_function_environment https://github.com/jasonwilliams/boa/blob/master/src/lib/exec.rs#L110

Because we don't do the same for blocks (if,while etc) any let values we create in blocks are added to the current environment, which will be the outer function most likely. This means the following JS works..

function outer() {
  var foo = "foo";
  if (true) {
    let bar = "bar";
  }

  return bar; // "bar"
}

What does the specification say?

When a Block or CaseBlock is evaluated a new declarative Environment Record is created and bindings for each block scoped variable, constant, function, or class declared in the block are instantiated in the Environment Record.

https://tc39.es/ecma262/#sec-blockdeclarationinstantiation

high level task

The process here is to create a new_declarative_environment when we hit a block and set that to the current environment, popping it off when we reach the end of our block. A potential bug this will cause is putting var declarations into the same scope, so we need to make sure vars still go into the function scope above.

low level

  • new_declaration_environment is already exposed here. Bring it into exec.rs so that it can be used similar to how new_function_environment is used.
  • lexical_environment.rs will need a way of setting bindings to the nearest function environment, rather than the current environment (to support var)
@jasonwilliams jasonwilliams added the Hacktoberfest Hacktoberfest 2021 - https://hacktoberfest.digitalocean.com label Oct 17, 2019
jasonwilliams pushed a commit that referenced this issue Oct 22, 2019
* Implement block scoped variable declarations

`const` and `let` are now scoped to the block, while `var` is scoped to
the surronding function (or global).

Another bigger change is that all tests have been changed to use `var`
instead of `let` or `const`. This is because every time `forward` is
called with some new Javascript to evaluate, we parse it as a block,
hence variables can only persist across calls to `forward` if they are
defined using `var`. I assume it is intentional to parse each call as a
separate block, because a block is the only `ExprDef` which can contain
multiple statements.

Closes #39

* Prefer environment parent over environment_stack

Instead of iterating over the `environment_stack` we rather use
`get_outer_environment` as it will be a better fit when asyncronous
functions are implemented.

* Ensure variable from outer scope is assigned

Variables that are defined outside a block should be changeable within
the scope. Just because variable is undefined does not mean it is not
initialized.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Hacktoberfest Hacktoberfest 2021 - https://hacktoberfest.digitalocean.com
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant