doc: improve styling consistency in VM docs
[platform/upstream/nodejs.git] / doc / api / vm.markdown
1 # Executing JavaScript
2
3     Stability: 2 - Stable
4
5 <!--name=vm-->
6
7 You can access this module with:
8
9     const vm = require('vm');
10
11 JavaScript code can be compiled and run immediately or compiled, saved, and run
12 later.
13
14 ## Class: Script
15
16 A class for holding precompiled scripts, and running them in specific sandboxes.
17
18 ### new vm.Script(code, options)
19
20 Creating a new `Script` compiles `code` but does not run it. Instead, the
21 created `vm.Script` object represents this compiled code. This script can be run
22 later many times using methods below. The returned script is not bound to any
23 global object. It is bound before each run, just for that run.
24
25 The options when creating a script are:
26
27 - `filename`: allows you to control the filename that shows up in any stack
28   traces produced from this script.
29 - `lineOffset`: allows you to add an offset to the line number that is
30   displayed in stack traces
31 - `columnOffset`: allows you to add an offset to the column number that is
32   displayed in stack traces
33 - `displayErrors`: whether or not to print any errors to stderr, with the
34   line of code that caused them highlighted, before throwing an exception.
35   Applies only to syntax errors compiling the code; errors while running the
36   code are controlled by the options to the script's methods.
37 - `timeout`: a number of milliseconds to execute `code` before terminating
38   execution. If execution is terminated, an [`Error`][] will be thrown.
39
40 ### script.runInContext(contextifiedSandbox[, options])
41
42 Similar to [`vm.runInContext()`][] but a method of a precompiled `Script`
43 object. `script.runInContext()` runs `script`'s compiled code in
44 `contextifiedSandbox` and returns the result. Running code does not have access
45 to local scope.
46
47 `script.runInContext()` takes the same options as
48 [`script.runInThisContext()`][].
49
50 Example: compile code that increments a global variable and sets one, then
51 execute the code multiple times. These globals are contained in the sandbox.
52
53     const util = require('util');
54     const vm = require('vm');
55
56     var sandbox = {
57       animal: 'cat',
58       count: 2
59     };
60
61     var context = new vm.createContext(sandbox);
62     var script = new vm.Script('count += 1; name = "kitty"');
63
64     for (var i = 0; i < 10; ++i) {
65       script.runInContext(context);
66     }
67
68     console.log(util.inspect(sandbox));
69
70     // { animal: 'cat', count: 12, name: 'kitty' }
71
72 Note that running untrusted code is a tricky business requiring great care.
73 `script.runInContext()` is quite useful, but safely running untrusted code
74 requires a separate process.
75
76 ### script.runInNewContext([sandbox][, options])
77
78 Similar to [`vm.runInNewContext()`][] but a method of a precompiled `Script`
79 object. `script.runInNewContext()` contextifies `sandbox` if passed or creates a
80 new contextified sandbox if it's omitted, and then runs `script`'s compiled code
81 with the sandbox as the global object and returns the result. Running code does
82 not have access to local scope.
83
84 `script.runInNewContext()` takes the same options as
85 [`script.runInThisContext()`][].
86
87 Example: compile code that sets a global variable, then execute the code
88 multiple times in different contexts. These globals are set on and contained in
89 the sandboxes.
90
91     const util = require('util');
92     const vm = require('vm');
93
94     const sandboxes = [{}, {}, {}];
95
96     const script = new vm.Script('globalVar = "set"');
97
98     sandboxes.forEach((sandbox) => {
99       script.runInNewContext(sandbox);
100     });
101
102     console.log(util.inspect(sandboxes));
103
104     // [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]
105
106 Note that running untrusted code is a tricky business requiring great care.
107 `script.runInNewContext()` is quite useful, but safely running untrusted code
108 requires a separate process.
109
110 ### script.runInThisContext([options])
111
112 Similar to [`vm.runInThisContext()`]() but a method of a precompiled `Script`
113 object. `script.runInThisContext()` runs `script`'s compiled code and returns
114 the result. Running code does not have access to local scope, but does have
115 access to the current `global` object.
116
117 Example of using `script.runInThisContext()` to compile code once and run it
118 multiple times:
119
120     const vm = require('vm');
121
122     global.globalVar = 0;
123
124     const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' });
125
126     for (var i = 0; i < 1000; ++i) {
127       script.runInThisContext();
128     }
129
130     console.log(globalVar);
131
132     // 1000
133
134 The options for running a script are:
135
136 - `filename`: allows you to control the filename that shows up in any stack
137   traces produced.
138 - `lineOffset`: allows you to add an offset to the line number that is
139   displayed in stack traces
140 - `columnOffset`: allows you to add an offset to the column number that is
141   displayed in stack traces
142 - `displayErrors`: whether or not to print any errors to stderr, with the
143   line of code that caused them highlighted, before throwing an exception.
144   Applies only to runtime errors executing the code; it is impossible to create
145   a `Script` instance with syntax errors, as the constructor will throw.
146 - `timeout`: a number of milliseconds to execute the script before terminating
147   execution. If execution is terminated, an [`Error`][] will be thrown.
148
149 ## vm.createContext([sandbox])
150
151 If given a `sandbox` object, will "contextify" that sandbox so that it can be
152 used in calls to [`vm.runInContext()`][] or [`script.runInContext()`][]. Inside
153 scripts run as such, `sandbox` will be the global object, retaining all its
154 existing properties but also having the built-in objects and functions any
155 standard [global object][] has. Outside of scripts run by the vm module,
156 `sandbox` will be unchanged.
157
158 If not given a sandbox object, returns a new, empty contextified sandbox object
159 you can use.
160
161 This function is useful for creating a sandbox that can be used to run multiple
162 scripts, e.g. if you were emulating a web browser it could be used to create a
163 single sandbox representing a window's global object, then run all `<script>`
164 tags together inside that sandbox.
165
166 ## vm.isContext(sandbox)
167
168 Returns whether or not a sandbox object has been contextified by calling
169 [`vm.createContext()`][] on it.
170
171 ## vm.runInContext(code, contextifiedSandbox[, options])
172
173 `vm.runInContext()` compiles `code`, then runs it in `contextifiedSandbox` and
174 returns the result. Running code does not have access to local scope. The
175 `contextifiedSandbox` object must have been previously contextified via
176 [`vm.createContext()`][]; it will be used as the global object for `code`.
177
178 `vm.runInContext()` takes the same options as [`vm.runInThisContext()`][].
179
180 Example: compile and execute different scripts in a single existing context.
181
182     const util = require('util');
183     const vm = require('vm');
184
185     const sandbox = { globalVar: 1 };
186     vm.createContext(sandbox);
187
188     for (var i = 0; i < 10; ++i) {
189         vm.runInContext('globalVar *= 2;', sandbox);
190     }
191     console.log(util.inspect(sandbox));
192
193     // { globalVar: 1024 }
194
195 Note that running untrusted code is a tricky business requiring great care.
196 `vm.runInContext()` is quite useful, but safely running untrusted code requires
197 a separate process.
198
199 ## vm.runInDebugContext(code)
200
201 `vm.runInDebugContext()` compiles and executes `code` inside the V8 debug
202 context. The primary use case is to get access to the V8 debug object:
203
204     const Debug = vm.runInDebugContext('Debug');
205     Debug.scripts().forEach(function(script) { console.log(script.name); });
206
207 Note that the debug context and object are intrinsically tied to V8's debugger
208 implementation and may change (or even get removed) without prior warning.
209
210 The debug object can also be exposed with the `--expose_debug_as=` switch.
211
212 ## vm.runInNewContext(code[, sandbox][, options])
213
214 `vm.runInNewContext()` compiles `code`, contextifies `sandbox` if passed or
215 creates a new contextified sandbox if it's omitted, and then runs the code with
216 the sandbox as the global object and returns the result.
217
218 `vm.runInNewContext()` takes the same options as [`vm.runInThisContext()`][].
219
220 Example: compile and execute code that increments a global variable and sets a
221 new one. These globals are contained in the sandbox.
222
223     const util = require('util');
224     const vm = require('vm');
225
226     const sandbox = {
227       animal: 'cat',
228       count: 2
229     };
230
231     vm.runInNewContext('count += 1; name = "kitty"', sandbox);
232     console.log(util.inspect(sandbox));
233
234     // { animal: 'cat', count: 3, name: 'kitty' }
235
236 Note that running untrusted code is a tricky business requiring great care.
237 `vm.runInNewContext()` is quite useful, but safely running untrusted code requires
238 a separate process.
239
240 ## vm.runInThisContext(code[, options])
241
242 `vm.runInThisContext()` compiles `code`, runs it and returns the result. Running
243 code does not have access to local scope, but does have access to the current
244 `global` object.
245
246 Example of using `vm.runInThisContext()` and [`eval()`][] to run the same code:
247
248     const vm = require('vm');
249     var localVar = 'initial value';
250
251     const vmResult = vm.runInThisContext('localVar = "vm";');
252     console.log('vmResult: ', vmResult);
253     console.log('localVar: ', localVar);
254
255     const evalResult = eval('localVar = "eval";');
256     console.log('evalResult: ', evalResult);
257     console.log('localVar: ', localVar);
258
259     // vmResult: 'vm', localVar: 'initial value'
260     // evalResult: 'eval', localVar: 'eval'
261
262 `vm.runInThisContext()` does not have access to the local scope, so `localVar`
263 is unchanged. [`eval()`][] does have access to the local scope, so `localVar` is
264 changed.
265
266 In this way `vm.runInThisContext()` is much like an [indirect `eval()` call][],
267 e.g. `(0,eval)('code')`. However, it also has the following additional options:
268
269 - `filename`: allows you to control the filename that shows up in any stack
270   traces produced.
271 - `lineOffset`: allows you to add an offset to the line number that is
272   displayed in stack traces
273 - `columnOffset`: allows you to add an offset to the column number that is
274   displayed in stack traces
275 - `displayErrors`: whether or not to print any errors to stderr, with the
276   line of code that caused them highlighted, before throwing an exception.
277   Will capture both syntax errors from compiling `code` and runtime errors
278   thrown by executing the compiled code. Defaults to `true`.
279 - `timeout`: a number of milliseconds to execute `code` before terminating
280   execution. If execution is terminated, an [`Error`][] will be thrown.
281
282 [indirect `eval()` call]: https://es5.github.io/#x10.4.2
283 [global object]: https://es5.github.io/#x15.1
284 [`Error`]: errors.html#errors_class_error
285 [`script.runInContext()`]: #vm_script_runincontext_contextifiedsandbox_options
286 [`script.runInThisContext()`]: #vm_script_runinthiscontext_options
287 [`vm.createContext()`]: #vm_vm_createcontext_sandbox
288 [`vm.runInContext()`]: #vm_vm_runincontext_code_contextifiedsandbox_options
289 [`vm.runInNewContext()`]: #vm_vm_runinnewcontext_code_sandbox_options
290 [`vm.runInThisContext()`]: #vm_vm_runinthiscontext_code_options
291 [`eval()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval