constructor(options = {}) {
		super();

		// Read all options
		const {
			timeout,
			sandbox,
			compiler = 'javascript',
			allowAsync: optAllowAsync = true
		} = options;
		const allowEval = options.eval !== false;
		const allowWasm = options.wasm !== false;
		const allowAsync = optAllowAsync && !options.fixAsync;

		// Early error if sandbox is not an object.
		if (sandbox && 'object' !== typeof sandbox) {
			throw new VMError('Sandbox must be object.');
		}

		// Early error if compiler can't be found.
		const resolvedCompiler = lookupCompiler(compiler);

		// Create a new context for this vm.
		const _context = createContext(undefined, {
			__proto__: null,
			codeGeneration: {
				__proto__: null,
				strings: allowEval,
				wasm: allowWasm
			}
		});

		const sandboxGlobal = getGlobalScript.runInContext(_context, DEFAULT_RUN_OPTIONS);

		// Initialize the sandbox bridge
		const {
			createBridge: sandboxCreateBridge
		} = bridgeScript.runInContext(_context, DEFAULT_RUN_OPTIONS)(sandboxGlobal);

		// Initialize the bridge
		const bridge = createBridge(sandboxCreateBridge, () => {});

		const data = {
			__proto__: null,
			allowAsync
		};

		if (getGeneratorFunctionScript) {
			data.GeneratorFunction = getGeneratorFunctionScript.runInContext(_context, DEFAULT_RUN_OPTIONS);
		}
		if (getAsyncFunctionScript) {
			data.AsyncFunction = getAsyncFunctionScript.runInContext(_context, DEFAULT_RUN_OPTIONS);
		}
		if (getAsyncGeneratorFunctionScript) {
			data.AsyncGeneratorFunction = getAsyncGeneratorFunctionScript.runInContext(_context, DEFAULT_RUN_OPTIONS);
		}

		// Create the bridge between the host and the sandbox.
		const internal = setupSandboxScript.runInContext(_context, DEFAULT_RUN_OPTIONS)(sandboxGlobal, HOST, bridge.other, data, _context);

		const runScript = (script) => {
			// This closure is intentional to hide _context and bridge since the allow to access the sandbox directly which is unsafe.
			let ret;
			try {
				ret = script.runInContext(_context, DEFAULT_RUN_OPTIONS);
			} catch (e) {
				throw bridge.from(e);
			}
			return bridge.from(ret);
		};

		const makeReadonly = (value, mock) => {
			try {
				internal.readonly(value, mock);
			} catch (e) {
				throw bridge.from(e);
			}
			return value;
		};

		const makeProtected = (value) => {
			const sandboxBridge = bridge.other;
			try {
				sandboxBridge.fromWithFactory(sandboxBridge.protectedFactory, value);
			} catch (e) {
				throw bridge.from(e);
			}
			return value;
		};

		const addProtoMapping = (hostProto, sandboxProto) => {
			const sandboxBridge = bridge.other;
			let otherProto;
			try {
				otherProto = sandboxBridge.from(sandboxProto);
				sandboxBridge.addProtoMapping(otherProto, hostProto);
			} catch (e) {
				throw bridge.from(e);
			}
			bridge.addProtoMapping(hostProto, otherProto);
		};

		const addProtoMappingFactory = (hostProto, sandboxProtoFactory) => {
			const sandboxBridge = bridge.other;
			const factory = () => {
				const proto = sandboxProtoFactory(this);
				bridge.addProtoMapping(hostProto, proto);
				return proto;
			};
			try {
				const otherProtoFactory = sandboxBridge.from(factory);
				sandboxBridge.addProtoMappingFactory(otherProtoFactory, hostProto);
			} catch (e) {
				throw bridge.from(e);
			}
		};

		// Define the properties of this object.
		// Use Object.defineProperties here to be able to
		// hide and set properties read-only.
		objectDefineProperties(this, {
			__proto__: null,
			timeout: {
				__proto__: null,
				value: timeout,
				writable: true,
				enumerable: true
			},
			compiler: {
				__proto__: null,
				value: compiler,
				enumerable: true
			},
			sandbox: {
				__proto__: null,
				value: bridge.from(sandboxGlobal),
				enumerable: true
			},
			_runScript: {__proto__: null, value: runScript},
			_makeReadonly: {__proto__: null, value: makeReadonly},
			_makeProtected: {__proto__: null, value: makeProtected},
			_addProtoMapping: {__proto__: null, value: addProtoMapping},
			_addProtoMappingFactory: {__proto__: null, value: addProtoMappingFactory},
			_compiler: {__proto__: null, value: resolvedCompiler},
			_allowAsync: {__proto__: null, value: allowAsync}
		});

		this.readonly(inspect);

		// prepare global sandbox
		if (sandbox) {
			this.setGlobals(sandbox);
		}
	}
Create a new VM instance.

@public
@param {Object} [options] - VM options.
@param {number} [options.timeout] - The amount of time until a call to {@link VM#run} will timeout.
@param {Object} [options.sandbox] - Objects that will be copied into the global object of the sandbox.
@param {(string|compileCallback)} [options.compiler="javascript"] - The compiler to use.
@param {boolean} [options.eval=true] - Allow the dynamic evaluation of code via eval(code) or Function(code)().<br>
Only available for node v10+.
@param {boolean} [options.wasm=true] - Allow to run wasm code.<br>
Only available for node v10+.
@param {boolean} [options.allowAsync=true] - Allows for async functions.
@throws {VMError} If the compiler is unknown.