Repository: node
Issue: vm: Function declarations should use [[Define]] instead of [[Set]] on the global object
Labels: vm,v8 engine

- **Version**: v13.8.0
- **Platform**: All; tested on **Travis CI** (**Ubuntu 16.04.6 LTS**)
- **Subsystem**: vm

## What steps will reproduce the bug?

```js
const vm = require("vm");

let impl = { status: "" };
let ctx = vm.createContext();
Object.defineProperty(ctx, "status", {
	configurable: true,
	enumerable: true,
	get() {
		return impl.status;
	},
	set(v) {
		impl.status = `${v}`;
	}
});

// https://github.com/web-platform-tests/wpt/blob/master/xhr/status-async.htm
vm.runInContext(`
function statusRequest(...args) {
	console.log(args.map(JSON.stringify).join("\t"));
}
function status(code, text, content, type) {
	statusRequest("GET", code, text, content, type);
	statusRequest("HEAD", code, text, content, type);
	statusRequest("CHICKEN", code, text, content, type);
}
status(204, "UNICORNSWIN", "", "")
status(401, "OH HELLO", "Not today.", "")
status(402, "FIVE BUCKS", "<x>402<\/x>", "text/xml")
status(402, "FREE", "Nice!", "text/doesnotmatter")
status(402, "402 TEH AWESOME", "", "")
status(502, "YO", "", "")
status(502, "lowercase", "SWEET POTATO", "text/plain")
status(503, "HOUSTON WE HAVE A", "503", "text/plain")
status(699, "WAY OUTTA RANGE", "699", "text/plain")
`, ctx);
```

## How often does it reproduce? Is there a required condition?

Always.

## What is the expected behavior?

The functions get defined using `[[DefineOwnProperty]]` as specified in [ECMA‑262 § 8.1.1.4.18 `CreateGlobalFunctionBinding`](https://tc39.es/ecma262/#sec-createglobalfunctionbinding).

<details>
<summary><strong>Expected log output</strong></summary>

<pre><table><tr><td>"GET"</td>	<td>204</td>	<td>"UNICORNSWIN"</td>	<td>""</td>	<td>""</td></tr>
<tr><td>"HEAD"</td>	<td>204</td>	<td>"UNICORNSWIN"</td>	<td>""</td>	<td>""</td></tr>
<tr><td>"CHICKEN"</td>	<td>204</td>	<td>"UNICORNSWIN"</td>	<td>""</td>	<td>""</td></tr>
<tr><td>"GET"</td>	<td>401</td>	<td>"OH HELLO"</td>	<td>"Not today."</td>	<td>""</td></tr>
<tr><td>"HEAD"</td>	<td>401</td>	<td>"OH HELLO"</td>	<td>"Not today."</td>	<td>""</td></tr>
<tr><td>"CHICKEN"</td>	<td>401</td>	<td>"OH HELLO"</td>	<td>"Not today."</td>	<td>""</td></tr>
<tr><td>"GET"</td>	<td>402</td>	<td>"FIVE BUCKS"</td>	<td>"<x>402</x>"</td>	<td>"text/xml"</td></tr>
<tr><td>"HEAD"</td>	<td>402</td>	<td>"FIVE BUCKS"</td>	<td>"<x>402</x>"</td>	<td>"text/xml"</td></tr>
<tr><td>"CHICKEN"</td>	<td>402</td>	<td>"FIVE BUCKS"</td>	<td>"<x>402</x>"</td>	<td>"text/xml"</td></tr>
<tr><td>"GET"</td>	<td>402</td>	<td>"FREE"</td>	<td>"Nice!"</td>	<td>"text/doesnotmatter"</td></tr>
<tr><td>"HEAD"</td>	<td>402</td>	<td>"FREE"</td>	<td>"Nice!"</td>	<td>"text/doesnotmatter"</td></tr>
<tr><td>"CHICKEN"</td>	<td>402</td>	<td>"FREE"</td>	<td>"Nice!"</td>	<td>"text/doesnotmatter"</td></tr>
<tr><td>"GET"</td>	<td>402</td>	<td>"402 TEH AWESOME"</td>	<td>""</td>	<td>""</td></tr>
<tr><td>"HEAD"</td>	<td>402</td>	<td>"402 TEH AWESOME"</td>	<td>""</td>	<td>""</td></tr>
<tr><td>"CHICKEN"</td>	<td>402</td>	<td>"402 TEH AWESOME"</td>	<td>""</td>	<td>""</td></tr>
<tr><td>"GET"</td>	<td>502</td>	<td>"YO"</td>	<td>""</td>	<td>""</td></tr>
<tr><td>"HEAD"</td>	<td>502</td>	<td>"YO"</td>	<td>""</td>	<td>""</td></tr>
<tr><td>"CHICKEN"</td>	<td>502</td>	<td>"YO"</td>	<td>""</td>	<td>""</td></tr>
<tr><td>"GET"</td>	<td>502</td>	<td>"lowercase"</td>	<td>"SWEET POTATO"</td>	<td>"text/plain"</td></tr>
<tr><td>"HEAD"</td>	<td>502</td>	<td>"lowercase"</td>	<td>"SWEET POTATO"</td>	<td>"text/plain"</td></tr>
<tr><td>"CHICKEN"</td>	<td>502</td>	<td>"lowercase"</td>	<td>"SWEET POTATO"</td>	<td>"text/plain"</td></tr>
<tr><td>"GET"</td>	<td>503</td>	<td>"HOUSTON WE HAVE A"</td>	<td>"503"</td>	<td>"text/plain"</td></tr>
<tr><td>"HEAD"</td>	<td>503</td>	<td>"HOUSTON WE HAVE A"</td>	<td>"503"</td>	<td>"text/plain"</td></tr>
<tr><td>"CHICKEN"</td>	<td>503</td>	<td>"HOUSTON WE HAVE A"</td>	<td>"503"</td>	<td>"text/plain"</td></tr>
<tr><td>"GET"</td>	<td>699</td>	<td>"WAY OUTTA RANGE"</td>	<td>"699"</td>	<td>"text/plain"</td></tr>
<tr><td>"HEAD"</td>	<td>699</td>	<td>"WAY OUTTA RANGE"</td>	<td>"699"</td>	<td>"text/plain"</td></tr>
<tr><td>"CHICKEN"</td>	<td>699</td>	<td>"WAY OUTTA RANGE"</td>	<td>"699"</td>	<td>"text/plain"</td></tr></table></pre>
</details>

## What do you see instead?

```
evalmachine.<anonymous>:10
status(204, "UNICORNSWIN", "", "")
^

Uncaught TypeError: status is not a function
    at evalmachine.<anonymous>:10:1
    at Script.runInContext (vm.js:131:20)
    at Object.runInContext (vm.js:295:6)
    at repl:1:4
    at Script.runInThisContext (vm.js:120:20)
    at REPLServer.defaultEval (repl.js:432:29)
    at bound (domain.js:429:14)
    at REPLServer.runBound [as eval] (domain.js:442:12)
    at REPLServer.onLine (repl.js:759:10)
    at REPLServer.emit (events.js:333:22)
```

## Additional information

Discovered in: <https://github.com/jsdom/jsdom/pull/2835#discussion_r379706437>

## See also
- <https://github.com/nodejs/node/issues/38918>