Repository: node
Issue: vm: in strict mode, assigning functions to certain globals throws, but succeeds
Labels: vm

<!--
Thank you for reporting an issue.

This issue tracker is for bugs and issues found within Node.js core.
If you require more general support please file an issue on our help
repo. https://github.com/nodejs/help


Please fill in as much of the template below as you're able.

Version: output of `node -v`
Platform: output of `uname -a` (UNIX), or output of `"$([Environment]::OSVersion | ForEach-Object VersionString) $(if ([Environment]::Is64BitOperatingSystem) { "x64" } else { "x86" })"` in PowerShell console (Windows)
Subsystem: if known, please specify affected core module name
-->

* **Version**: v14.17.0
* **Platform**: Linux 5.8.0-53-generic x86_64 x86_64 x86_64 GNU/Linux
* **Subsystem**: vm

### What steps will reproduce the bug?

<!--
Enter details about your bug, preferably a simple code snippet that can be
run using `node` directly without installing third-party dependencies.
-->

```js
const vm = require('vm');

vm.runInNewContext(`
"use strict";

try {
  Foo = function myfoo() {};
  console.log("function-valued assignment to undeclared global Foo did not throw");
} catch (error) {
  console.log("function-valued assignment to undeclared global Foo threw", error);
}

try {
  console.log("Foo is", Foo);
} catch (error) {
  console.log("Foo was not set");
}
`, {console});
```

### How often does it reproduce? Is there a required condition?

Requires strict mode, requires that the value be a function.

Can be reproduced with an undeclared global, or with a global added to the context object _post-contextualization_. Cannot be reproduced with a global defined in the script, nor with a global added to the context object _pre-contextualization_.

<details>
<summary>Post-contextualization global example</summary>

```js
const vm = require('vm');

const context = vm.createContext({console});
context.Foo = function foo() {};

vm.runInNewContext(`
"use strict";

try {
  console.log("Foo is", Foo);
} catch (error) {
  console.log("Foo is not set");
}

try {
  Foo = function myfoo() {};
  console.log("function-valued assignment to global Foo did not throw");
} catch (error) {
  console.log("function-valued assignment to global Foo threw", error);
}

try {
  console.log("Foo is", Foo);
} catch (error) {
  console.log("Foo is not set");
}
`, context);
```

</details>

### What is the expected behavior?

<!--
If possible please provide textual output instead of screenshots.
-->

With an undeclared global, the assignment should throw, and the global should not be set. This is what happens when running the same code in node directly, rather than in `vm`.

With a declared global, the assignment should not throw, and the global should be set.

### What do you see instead?

<!--
If possible please provide textual output instead of screenshots.
-->

The assignment throws, but is still performed.

```
function-valued assignment to undeclared global Foo threw ReferenceError: Foo is not defined
...
Foo is [Function: myfoo]
```

### Additional information

https://github.com/nodejs/node/blob/a172397237af2dbc0c28af45f9edf067c9df544f/src/node_contextify.cc#L436-L443 seems like a potential culprit, although I don't really understand what's going on there.