Files
kiss-flixel/feedback-server/externs/node/Vm.hx

258 lines
9.5 KiB
Haxe

package node;
/**
The `node:vm` module enables compiling and running code within V8 Virtual
Machine contexts.
**The `node:vm` module is not a security**
**mechanism. Do not use it to run untrusted code.**
JavaScript code can be compiled and run immediately or
compiled, saved, and run later.
A common use case is to run the code in a different V8 Context. This means
invoked code has a different global object than the invoking code.
One can provide the context by `contextifying` an
object. The invoked code treats any property in the context like a
global variable. Any changes to global variables caused by the invoked
code are reflected in the context object.
```js
const vm = require('node:vm');
const x = 1;
const context = { x: 2 };
vm.createContext(context); // Contextify the object.
const code = 'x += 40; var y = 17;';
// `x` and `y` are global variables in the context.
// Initially, x has the value 2 because that is the value of context.x.
vm.runInContext(code, context);
console.log(context.x); // 42
console.log(context.y); // 17
console.log(x); // 1; y is not defined.
```
**/
@:jsRequire("vm") @valueModuleOnly extern class Vm {
/**
If given a `contextObject`, the `vm.createContext()` method will `prepare
that object` so that it can be used in calls to {@link runInContext} or `script.runInContext()`. Inside such scripts,
the `contextObject` will be the global object, retaining all of its existing
properties but also having the built-in objects and functions any standard [global object](https://es5.github.io/#x15.1) has. Outside of scripts run by the vm module, global variables
will remain unchanged.
```js
const vm = require('node:vm');
global.globalVar = 3;
const context = { globalVar: 1 };
vm.createContext(context);
vm.runInContext('globalVar *= 2;', context);
console.log(context);
// Prints: { globalVar: 2 }
console.log(global.globalVar);
// Prints: 3
```
If `contextObject` is omitted (or passed explicitly as `undefined`), a new,
empty `contextified` object will be returned.
The `vm.createContext()` method is primarily useful for creating a single
context that can be used to run multiple scripts. For instance, if emulating a
web browser, the method can be used to create a single context representing a
window's global object, then run all `<script>` tags together within that
context.
The provided `name` and `origin` of the context are made visible through the
Inspector API.
**/
static function createContext(?sandbox:node.vm.Context, ?options:node.vm.CreateContextOptions):node.vm.Context;
/**
Returns `true` if the given `object` object has been `contextified` using {@link createContext}.
**/
static function isContext(sandbox:node.vm.Context):Bool;
/**
The `vm.runInContext()` method compiles `code`, runs it within the context of
the `contextifiedObject`, then returns the result. Running code does not have
access to the local scope. The `contextifiedObject` object _must_ have been
previously `contextified` using the {@link createContext} method.
If `options` is a string, then it specifies the filename.
The following example compiles and executes different scripts using a single `contextified` object:
```js
const vm = require('node:vm');
const contextObject = { globalVar: 1 };
vm.createContext(contextObject);
for (let i = 0; i < 10; ++i) {
vm.runInContext('globalVar *= 2;', contextObject);
}
console.log(contextObject);
// Prints: { globalVar: 1024 }
```
**/
static function runInContext(code:String, contextifiedObject:node.vm.Context, ?options:ts.AnyOf2<String, node.vm.RunningCodeOptions>):Dynamic;
/**
The `vm.runInNewContext()` first contextifies the given `contextObject` (or
creates a new `contextObject` if passed as `undefined`), compiles the `code`,
runs it within the created context, then returns the result. Running code
does not have access to the local scope.
If `options` is a string, then it specifies the filename.
The following example compiles and executes code that increments a global
variable and sets a new one. These globals are contained in the `contextObject`.
```js
const vm = require('node:vm');
const contextObject = {
animal: 'cat',
count: 2,
};
vm.runInNewContext('count += 1; name = "kitty"', contextObject);
console.log(contextObject);
// Prints: { animal: 'cat', count: 3, name: 'kitty' }
```
**/
static function runInNewContext(code:String, ?contextObject:node.vm.Context, ?options:ts.AnyOf2<String, node.vm.RunningCodeInNewContextOptions>):Dynamic;
/**
`vm.runInThisContext()` compiles `code`, runs it within the context of the
current `global` and returns the result. Running code does not have access to
local scope, but does have access to the current `global` object.
If `options` is a string, then it specifies the filename.
The following example illustrates using both `vm.runInThisContext()` and
the JavaScript [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) function to run the same code:
```js
const vm = require('node:vm');
let localVar = 'initial value';
const vmResult = vm.runInThisContext('localVar = "vm";');
console.log(`vmResult: '${vmResult}', localVar: '${localVar}'`);
// Prints: vmResult: 'vm', localVar: 'initial value'
const evalResult = eval('localVar = "eval";');
console.log(`evalResult: '${evalResult}', localVar: '${localVar}'`);
// Prints: evalResult: 'eval', localVar: 'eval'
```
Because `vm.runInThisContext()` does not have access to the local scope,`localVar` is unchanged. In contrast,
[`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) _does_ have access to the
local scope, so the value `localVar` is changed. In this way`vm.runInThisContext()` is much like an [indirect `eval()` call](https://es5.github.io/#x10.4.2), e.g.`(0,eval)('code')`.
## Example: Running an HTTP server within a VM
When using either `script.runInThisContext()` or {@link runInThisContext}, the code is executed within the current V8 global
context. The code passed to this VM context will have its own isolated scope.
In order to run a simple web server using the `node:http` module the code passed
to the context must either call `require('node:http')` on its own, or have a
reference to the `node:http` module passed to it. For instance:
```js
'use strict';
const vm = require('node:vm');
const code = `
((require) => {
const http = require('node:http');
http.createServer((request, response) => {
response.writeHead(200, { 'Content-Type': 'text/plain' });
response.end('Hello World\\n');
}).listen(8124);
console.log('Server running at http://127.0.0.1:8124/');
})`;
vm.runInThisContext(code)(require);
```
The `require()` in the above case shares the state with the context it is
passed from. This may introduce risks when untrusted code is executed, e.g.
altering objects in the context in unwanted ways.
**/
static function runInThisContext(code:String, ?options:ts.AnyOf2<String, node.vm.RunningCodeOptions>):Dynamic;
/**
Compiles the given code into the provided context (if no context is
supplied, the current context is used), and returns it wrapped inside a
function with the given `params`.
**/
static function compileFunction(code:String, ?params:haxe.ds.ReadOnlyArray<String>, ?options:node.vm.CompileFunctionOptions):js.lib.IFunction & {
@:optional
var cachedData : node.buffer.Buffer;
@:optional
var cachedDataProduced : Bool;
@:optional
var cachedDataRejected : Bool;
};
/**
Measure the memory known to V8 and used by all contexts known to the
current V8 isolate, or the main context.
The format of the object that the returned Promise may resolve with is
specific to the V8 engine and may change from one version of V8 to the next.
The returned result is different from the statistics returned by`v8.getHeapSpaceStatistics()` in that `vm.measureMemory()` measure the
memory reachable by each V8 specific contexts in the current instance of
the V8 engine, while the result of `v8.getHeapSpaceStatistics()` measure
the memory occupied by each heap space in the current V8 instance.
```js
const vm = require('node:vm');
// Measure the memory used by the main context.
vm.measureMemory({ mode: 'summary' })
// This is the same as vm.measureMemory()
.then((result) => {
// The current format is:
// {
// total: {
// jsMemoryEstimate: 2418479, jsMemoryRange: [ 2418479, 2745799 ]
// }
// }
console.log(result);
});
const context = vm.createContext({ a: 1 });
vm.measureMemory({ mode: 'detailed', execution: 'eager' })
.then((result) => {
// Reference the context here so that it won't be GC'ed
// until the measurement is complete.
console.log(context.a);
// {
// total: {
// jsMemoryEstimate: 2574732,
// jsMemoryRange: [ 2574732, 2904372 ]
// },
// current: {
// jsMemoryEstimate: 2438996,
// jsMemoryRange: [ 2438996, 2768636 ]
// },
// other: [
// {
// jsMemoryEstimate: 135736,
// jsMemoryRange: [ 135736, 465376 ]
// }
// ]
// }
console.log(result);
});
```
**/
static function measureMemory(?options:node.vm.MeasureMemoryOptions):js.lib.Promise<node.vm.MemoryMeasurement>;
}