You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							1011 lines
						
					
					
						
							28 KiB
						
					
					
				
			
		
		
	
	
							1011 lines
						
					
					
						
							28 KiB
						
					
					
				'use strict';
 | 
						|
 | 
						|
/**
 | 
						|
 * __        ___    ____  _   _ ___ _   _  ____
 | 
						|
 * \ \      / / \  |  _ \| \ | |_ _| \ | |/ ___|
 | 
						|
 *  \ \ /\ / / _ \ | |_) |  \| || ||  \| | |  _
 | 
						|
 *   \ V  V / ___ \|  _ <| |\  || || |\  | |_| |
 | 
						|
 *    \_/\_/_/   \_\_| \_\_| \_|___|_| \_|\____|
 | 
						|
 *
 | 
						|
 * This file is critical for vm2. It implements the bridge between the host and the sandbox.
 | 
						|
 * If you do not know exactly what you are doing, you should NOT edit this file.
 | 
						|
 *
 | 
						|
 * The file is loaded in the host and sandbox to handle objects in both directions.
 | 
						|
 * This is done to ensure that RangeErrors are from the correct context.
 | 
						|
 * The boundary between the sandbox and host might throw RangeErrors from both contexts.
 | 
						|
 * Therefore, thisFromOther and friends can handle objects from both domains.
 | 
						|
 *
 | 
						|
 * Method parameters have comments to tell from which context they came.
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
const globalsList = [
 | 
						|
	'Number',
 | 
						|
	'String',
 | 
						|
	'Boolean',
 | 
						|
	'Date',
 | 
						|
	'RegExp',
 | 
						|
	'Map',
 | 
						|
	'WeakMap',
 | 
						|
	'Set',
 | 
						|
	'WeakSet',
 | 
						|
	'Promise',
 | 
						|
	'Function'
 | 
						|
];
 | 
						|
 | 
						|
const errorsList = [
 | 
						|
	'RangeError',
 | 
						|
	'ReferenceError',
 | 
						|
	'SyntaxError',
 | 
						|
	'TypeError',
 | 
						|
	'EvalError',
 | 
						|
	'URIError',
 | 
						|
	'Error'
 | 
						|
];
 | 
						|
 | 
						|
const OPNA = 'Operation not allowed on contextified object.';
 | 
						|
 | 
						|
const thisGlobalPrototypes = {
 | 
						|
	__proto__: null,
 | 
						|
	Object: Object.prototype,
 | 
						|
	Array: Array.prototype
 | 
						|
};
 | 
						|
 | 
						|
for (let i = 0; i < globalsList.length; i++) {
 | 
						|
	const key = globalsList[i];
 | 
						|
	const g = global[key];
 | 
						|
	if (g) thisGlobalPrototypes[key] = g.prototype;
 | 
						|
}
 | 
						|
 | 
						|
for (let i = 0; i < errorsList.length; i++) {
 | 
						|
	const key = errorsList[i];
 | 
						|
	const g = global[key];
 | 
						|
	if (g) thisGlobalPrototypes[key] = g.prototype;
 | 
						|
}
 | 
						|
 | 
						|
const {
 | 
						|
	getPrototypeOf: thisReflectGetPrototypeOf,
 | 
						|
	setPrototypeOf: thisReflectSetPrototypeOf,
 | 
						|
	defineProperty: thisReflectDefineProperty,
 | 
						|
	deleteProperty: thisReflectDeleteProperty,
 | 
						|
	getOwnPropertyDescriptor: thisReflectGetOwnPropertyDescriptor,
 | 
						|
	isExtensible: thisReflectIsExtensible,
 | 
						|
	preventExtensions: thisReflectPreventExtensions,
 | 
						|
	apply: thisReflectApply,
 | 
						|
	construct: thisReflectConstruct,
 | 
						|
	set: thisReflectSet,
 | 
						|
	get: thisReflectGet,
 | 
						|
	has: thisReflectHas,
 | 
						|
	ownKeys: thisReflectOwnKeys,
 | 
						|
	enumerate: thisReflectEnumerate,
 | 
						|
} = Reflect;
 | 
						|
 | 
						|
const thisObject = Object;
 | 
						|
const {
 | 
						|
	freeze: thisObjectFreeze,
 | 
						|
	prototype: thisObjectPrototype
 | 
						|
} = thisObject;
 | 
						|
const thisObjectHasOwnProperty = thisObjectPrototype.hasOwnProperty;
 | 
						|
const ThisProxy = Proxy;
 | 
						|
const ThisWeakMap = WeakMap;
 | 
						|
const {
 | 
						|
	get: thisWeakMapGet,
 | 
						|
	set: thisWeakMapSet
 | 
						|
} = ThisWeakMap.prototype;
 | 
						|
const ThisMap = Map;
 | 
						|
const thisMapGet = ThisMap.prototype.get;
 | 
						|
const thisMapSet = ThisMap.prototype.set;
 | 
						|
const thisFunction = Function;
 | 
						|
const thisFunctionBind = thisFunction.prototype.bind;
 | 
						|
const thisArrayIsArray = Array.isArray;
 | 
						|
const thisErrorCaptureStackTrace = Error.captureStackTrace;
 | 
						|
 | 
						|
const thisSymbolToString = Symbol.prototype.toString;
 | 
						|
const thisSymbolToStringTag = Symbol.toStringTag;
 | 
						|
const thisSymbolIterator = Symbol.iterator;
 | 
						|
const thisSymbolNodeJSUtilInspectCustom = Symbol.for('nodejs.util.inspect.custom');
 | 
						|
 | 
						|
/**
 | 
						|
 * VMError.
 | 
						|
 *
 | 
						|
 * @public
 | 
						|
 * @extends {Error}
 | 
						|
 */
 | 
						|
class VMError extends Error {
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Create VMError instance.
 | 
						|
	 *
 | 
						|
	 * @public
 | 
						|
	 * @param {string} message - Error message.
 | 
						|
	 * @param {string} code - Error code.
 | 
						|
	 */
 | 
						|
	constructor(message, code) {
 | 
						|
		super(message);
 | 
						|
 | 
						|
		this.name = 'VMError';
 | 
						|
		this.code = code;
 | 
						|
 | 
						|
		thisErrorCaptureStackTrace(this, this.constructor);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
thisGlobalPrototypes['VMError'] = VMError.prototype;
 | 
						|
 | 
						|
function thisUnexpected() {
 | 
						|
	return new VMError('Unexpected');
 | 
						|
}
 | 
						|
 | 
						|
if (!thisReflectSetPrototypeOf(exports, null)) throw thisUnexpected();
 | 
						|
 | 
						|
function thisSafeGetOwnPropertyDescriptor(obj, key) {
 | 
						|
	const desc = thisReflectGetOwnPropertyDescriptor(obj, key);
 | 
						|
	if (!desc) return desc;
 | 
						|
	if (!thisReflectSetPrototypeOf(desc, null)) throw thisUnexpected();
 | 
						|
	return desc;
 | 
						|
}
 | 
						|
 | 
						|
function thisThrowCallerCalleeArgumentsAccess(key) {
 | 
						|
	'use strict';
 | 
						|
	thisThrowCallerCalleeArgumentsAccess[key];
 | 
						|
	return thisUnexpected();
 | 
						|
}
 | 
						|
 | 
						|
function thisIdMapping(factory, other) {
 | 
						|
	return other;
 | 
						|
}
 | 
						|
 | 
						|
const thisThrowOnKeyAccessHandler = thisObjectFreeze({
 | 
						|
	__proto__: null,
 | 
						|
	get(target, key, receiver) {
 | 
						|
		if (typeof key === 'symbol') {
 | 
						|
			key = thisReflectApply(thisSymbolToString, key, []);
 | 
						|
		}
 | 
						|
		throw new VMError(`Unexpected access to key '${key}'`);
 | 
						|
	}
 | 
						|
});
 | 
						|
 | 
						|
const emptyForzenObject = thisObjectFreeze({
 | 
						|
	__proto__: null
 | 
						|
});
 | 
						|
 | 
						|
const thisThrowOnKeyAccess = new ThisProxy(emptyForzenObject, thisThrowOnKeyAccessHandler);
 | 
						|
 | 
						|
function SafeBase() {}
 | 
						|
 | 
						|
if (!thisReflectDefineProperty(SafeBase, 'prototype', {
 | 
						|
	__proto__: null,
 | 
						|
	value: thisThrowOnKeyAccess
 | 
						|
})) throw thisUnexpected();
 | 
						|
 | 
						|
function SHARED_FUNCTION() {}
 | 
						|
 | 
						|
const TEST_PROXY_HANDLER = thisObjectFreeze({
 | 
						|
	__proto__: thisThrowOnKeyAccess,
 | 
						|
	construct() {
 | 
						|
		return this;
 | 
						|
	}
 | 
						|
});
 | 
						|
 | 
						|
function thisIsConstructor(obj) {
 | 
						|
	// Note: obj@any(unsafe)
 | 
						|
	const Func = new ThisProxy(obj, TEST_PROXY_HANDLER);
 | 
						|
	try {
 | 
						|
		// eslint-disable-next-line no-new
 | 
						|
		new Func();
 | 
						|
		return true;
 | 
						|
	} catch (e) {
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
function thisCreateTargetObject(obj, proto) {
 | 
						|
	// Note: obj@any(unsafe) proto@any(unsafe) returns@this(unsafe) throws@this(unsafe)
 | 
						|
	let base;
 | 
						|
	if (typeof obj === 'function') {
 | 
						|
		if (thisIsConstructor(obj)) {
 | 
						|
			// Bind the function since bound functions do not have a prototype property.
 | 
						|
			base = thisReflectApply(thisFunctionBind, SHARED_FUNCTION, [null]);
 | 
						|
		} else {
 | 
						|
			base = () => {};
 | 
						|
		}
 | 
						|
	} else if (thisArrayIsArray(obj)) {
 | 
						|
		base = [];
 | 
						|
	} else {
 | 
						|
		return {__proto__: proto};
 | 
						|
	}
 | 
						|
	if (!thisReflectSetPrototypeOf(base, proto)) throw thisUnexpected();
 | 
						|
	return base;
 | 
						|
}
 | 
						|
 | 
						|
function createBridge(otherInit, registerProxy) {
 | 
						|
 | 
						|
	const mappingOtherToThis = new ThisWeakMap();
 | 
						|
	const protoMappings = new ThisMap();
 | 
						|
	const protoName = new ThisMap();
 | 
						|
 | 
						|
	function thisAddProtoMapping(proto, other, name) {
 | 
						|
		// Note: proto@this(unsafe) other@other(unsafe) name@this(unsafe) throws@this(unsafe)
 | 
						|
		thisReflectApply(thisMapSet, protoMappings, [proto, thisIdMapping]);
 | 
						|
		thisReflectApply(thisMapSet, protoMappings, [other,
 | 
						|
			(factory, object) => thisProxyOther(factory, object, proto)]);
 | 
						|
		if (name) thisReflectApply(thisMapSet, protoName, [proto, name]);
 | 
						|
	}
 | 
						|
 | 
						|
	function thisAddProtoMappingFactory(protoFactory, other, name) {
 | 
						|
		// Note: protoFactory@this(unsafe) other@other(unsafe) name@this(unsafe) throws@this(unsafe)
 | 
						|
		let proto;
 | 
						|
		thisReflectApply(thisMapSet, protoMappings, [other,
 | 
						|
			(factory, object) => {
 | 
						|
				if (!proto) {
 | 
						|
					proto = protoFactory();
 | 
						|
					thisReflectApply(thisMapSet, protoMappings, [proto, thisIdMapping]);
 | 
						|
					if (name) thisReflectApply(thisMapSet, protoName, [proto, name]);
 | 
						|
				}
 | 
						|
				return thisProxyOther(factory, object, proto);
 | 
						|
			}]);
 | 
						|
	}
 | 
						|
 | 
						|
	const result = {
 | 
						|
		__proto__: null,
 | 
						|
		globalPrototypes: thisGlobalPrototypes,
 | 
						|
		safeGetOwnPropertyDescriptor: thisSafeGetOwnPropertyDescriptor,
 | 
						|
		fromArguments: thisFromOtherArguments,
 | 
						|
		from: thisFromOther,
 | 
						|
		fromWithFactory: thisFromOtherWithFactory,
 | 
						|
		ensureThis: thisEnsureThis,
 | 
						|
		mapping: mappingOtherToThis,
 | 
						|
		connect: thisConnect,
 | 
						|
		reflectSet: thisReflectSet,
 | 
						|
		reflectGet: thisReflectGet,
 | 
						|
		reflectDefineProperty: thisReflectDefineProperty,
 | 
						|
		reflectDeleteProperty: thisReflectDeleteProperty,
 | 
						|
		reflectApply: thisReflectApply,
 | 
						|
		reflectConstruct: thisReflectConstruct,
 | 
						|
		reflectHas: thisReflectHas,
 | 
						|
		reflectOwnKeys: thisReflectOwnKeys,
 | 
						|
		reflectEnumerate: thisReflectEnumerate,
 | 
						|
		reflectGetPrototypeOf: thisReflectGetPrototypeOf,
 | 
						|
		reflectIsExtensible: thisReflectIsExtensible,
 | 
						|
		reflectPreventExtensions: thisReflectPreventExtensions,
 | 
						|
		objectHasOwnProperty: thisObjectHasOwnProperty,
 | 
						|
		weakMapSet: thisWeakMapSet,
 | 
						|
		addProtoMapping: thisAddProtoMapping,
 | 
						|
		addProtoMappingFactory: thisAddProtoMappingFactory,
 | 
						|
		defaultFactory,
 | 
						|
		protectedFactory,
 | 
						|
		readonlyFactory,
 | 
						|
		VMError
 | 
						|
	};
 | 
						|
 | 
						|
	const isHost = typeof otherInit !== 'object';
 | 
						|
 | 
						|
	if (isHost) {
 | 
						|
		otherInit = otherInit(result, registerProxy);
 | 
						|
	}
 | 
						|
 | 
						|
	result.other = otherInit;
 | 
						|
 | 
						|
	const {
 | 
						|
		globalPrototypes: otherGlobalPrototypes,
 | 
						|
		safeGetOwnPropertyDescriptor: otherSafeGetOwnPropertyDescriptor,
 | 
						|
		fromArguments: otherFromThisArguments,
 | 
						|
		from: otherFromThis,
 | 
						|
		mapping: mappingThisToOther,
 | 
						|
		reflectSet: otherReflectSet,
 | 
						|
		reflectGet: otherReflectGet,
 | 
						|
		reflectDefineProperty: otherReflectDefineProperty,
 | 
						|
		reflectDeleteProperty: otherReflectDeleteProperty,
 | 
						|
		reflectApply: otherReflectApply,
 | 
						|
		reflectConstruct: otherReflectConstruct,
 | 
						|
		reflectHas: otherReflectHas,
 | 
						|
		reflectOwnKeys: otherReflectOwnKeys,
 | 
						|
		reflectEnumerate: otherReflectEnumerate,
 | 
						|
		reflectGetPrototypeOf: otherReflectGetPrototypeOf,
 | 
						|
		reflectIsExtensible: otherReflectIsExtensible,
 | 
						|
		reflectPreventExtensions: otherReflectPreventExtensions,
 | 
						|
		objectHasOwnProperty: otherObjectHasOwnProperty,
 | 
						|
		weakMapSet: otherWeakMapSet
 | 
						|
	} = otherInit;
 | 
						|
 | 
						|
	function thisOtherHasOwnProperty(object, key) {
 | 
						|
		// Note: object@other(safe) key@prim throws@this(unsafe)
 | 
						|
		try {
 | 
						|
			return otherReflectApply(otherObjectHasOwnProperty, object, [key]) === true;
 | 
						|
		} catch (e) { // @other(unsafe)
 | 
						|
			throw thisFromOtherForThrow(e);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	function thisDefaultGet(handler, object, key, desc) {
 | 
						|
		// Note: object@other(unsafe) key@prim desc@other(safe)
 | 
						|
		let ret; // @other(unsafe)
 | 
						|
		if (desc.get || desc.set) {
 | 
						|
			const getter = desc.get;
 | 
						|
			if (!getter) return undefined;
 | 
						|
			try {
 | 
						|
				ret = otherReflectApply(getter, object, [key]);
 | 
						|
			} catch (e) {
 | 
						|
				throw thisFromOtherForThrow(e);
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			ret = desc.value;
 | 
						|
		}
 | 
						|
		return handler.fromOtherWithContext(ret);
 | 
						|
	}
 | 
						|
 | 
						|
	function otherFromThisIfAvailable(to, from, key) {
 | 
						|
		// Note: to@other(safe) from@this(safe) key@prim throws@this(unsafe)
 | 
						|
		if (!thisReflectApply(thisObjectHasOwnProperty, from, [key])) return false;
 | 
						|
		try {
 | 
						|
			to[key] = otherFromThis(from[key]);
 | 
						|
		} catch (e) { // @other(unsafe)
 | 
						|
			throw thisFromOtherForThrow(e);
 | 
						|
		}
 | 
						|
		return true;
 | 
						|
	}
 | 
						|
 | 
						|
	class BaseHandler extends SafeBase {
 | 
						|
 | 
						|
		constructor(object) {
 | 
						|
			// Note: object@other(unsafe) throws@this(unsafe)
 | 
						|
			super();
 | 
						|
			this.objectWrapper = () => object;
 | 
						|
		}
 | 
						|
 | 
						|
		getObject() {
 | 
						|
			return this.objectWrapper();
 | 
						|
		}
 | 
						|
 | 
						|
		getFactory() {
 | 
						|
			return defaultFactory;
 | 
						|
		}
 | 
						|
 | 
						|
		fromOtherWithContext(other) {
 | 
						|
			// Note: other@other(unsafe) throws@this(unsafe)
 | 
						|
			return thisFromOtherWithFactory(this.getFactory(), other);
 | 
						|
		}
 | 
						|
 | 
						|
		doPreventExtensions(target, object, factory) {
 | 
						|
			// Note: target@this(unsafe) object@other(unsafe) throws@this(unsafe)
 | 
						|
			let keys; // @other(safe-array-of-prim)
 | 
						|
			try {
 | 
						|
				keys = otherReflectOwnKeys(object);
 | 
						|
			} catch (e) { // @other(unsafe)
 | 
						|
				throw thisFromOtherForThrow(e);
 | 
						|
			}
 | 
						|
			for (let i = 0; i < keys.length; i++) {
 | 
						|
				const key = keys[i]; // @prim
 | 
						|
				let desc;
 | 
						|
				try {
 | 
						|
					desc = otherSafeGetOwnPropertyDescriptor(object, key);
 | 
						|
				} catch (e) { // @other(unsafe)
 | 
						|
					throw thisFromOtherForThrow(e);
 | 
						|
				}
 | 
						|
				if (!desc) continue;
 | 
						|
				if (!desc.configurable) {
 | 
						|
					const current = thisSafeGetOwnPropertyDescriptor(target, key);
 | 
						|
					if (current && !current.configurable) continue;
 | 
						|
					if (desc.get || desc.set) {
 | 
						|
						desc.get = this.fromOtherWithContext(desc.get);
 | 
						|
						desc.set = this.fromOtherWithContext(desc.set);
 | 
						|
					} else if (typeof object === 'function' && (key === 'caller' || key === 'callee' || key === 'arguments')) {
 | 
						|
						desc.value = null;
 | 
						|
					} else {
 | 
						|
						desc.value = this.fromOtherWithContext(desc.value);
 | 
						|
					}
 | 
						|
				} else {
 | 
						|
					if (desc.get || desc.set) {
 | 
						|
						desc = {
 | 
						|
							__proto__: null,
 | 
						|
							configurable: true,
 | 
						|
							enumerable: desc.enumerable,
 | 
						|
							writable: true,
 | 
						|
							value: null
 | 
						|
						};
 | 
						|
					} else {
 | 
						|
						desc.value = null;
 | 
						|
					}
 | 
						|
				}
 | 
						|
				if (!thisReflectDefineProperty(target, key, desc)) throw thisUnexpected();
 | 
						|
			}
 | 
						|
			if (!thisReflectPreventExtensions(target)) throw thisUnexpected();
 | 
						|
		}
 | 
						|
 | 
						|
		get(target, key, receiver) {
 | 
						|
			// Note: target@this(unsafe) key@prim receiver@this(unsafe) throws@this(unsafe)
 | 
						|
			const object = this.getObject(); // @other(unsafe)
 | 
						|
			switch (key) {
 | 
						|
				case 'constructor': {
 | 
						|
					const desc = otherSafeGetOwnPropertyDescriptor(object, key);
 | 
						|
					if (desc) return thisDefaultGet(this, object, key, desc);
 | 
						|
					const proto = thisReflectGetPrototypeOf(target);
 | 
						|
					return proto === null ? undefined : proto.constructor;
 | 
						|
				}
 | 
						|
				case '__proto__': {
 | 
						|
					const desc = otherSafeGetOwnPropertyDescriptor(object, key);
 | 
						|
					if (desc) return thisDefaultGet(this, object, key, desc);
 | 
						|
					return thisReflectGetPrototypeOf(target);
 | 
						|
				}
 | 
						|
				case thisSymbolToStringTag:
 | 
						|
					if (!thisOtherHasOwnProperty(object, thisSymbolToStringTag)) {
 | 
						|
						const proto = thisReflectGetPrototypeOf(target);
 | 
						|
						const name = thisReflectApply(thisMapGet, protoName, [proto]);
 | 
						|
						if (name) return name;
 | 
						|
					}
 | 
						|
					break;
 | 
						|
				case 'arguments':
 | 
						|
				case 'caller':
 | 
						|
				case 'callee':
 | 
						|
					if (typeof object === 'function' && thisOtherHasOwnProperty(object, key)) {
 | 
						|
						throw thisThrowCallerCalleeArgumentsAccess(key);
 | 
						|
					}
 | 
						|
					break;
 | 
						|
			}
 | 
						|
			let ret; // @other(unsafe)
 | 
						|
			try {
 | 
						|
				ret = otherReflectGet(object, key);
 | 
						|
			} catch (e) { // @other(unsafe)
 | 
						|
				throw thisFromOtherForThrow(e);
 | 
						|
			}
 | 
						|
			return this.fromOtherWithContext(ret);
 | 
						|
		}
 | 
						|
 | 
						|
		set(target, key, value, receiver) {
 | 
						|
			// Note: target@this(unsafe) key@prim value@this(unsafe) receiver@this(unsafe) throws@this(unsafe)
 | 
						|
			const object = this.getObject(); // @other(unsafe)
 | 
						|
			if (key === '__proto__' && !thisOtherHasOwnProperty(object, key)) {
 | 
						|
				return this.setPrototypeOf(target, value);
 | 
						|
			}
 | 
						|
			try {
 | 
						|
				value = otherFromThis(value);
 | 
						|
				return otherReflectSet(object, key, value) === true;
 | 
						|
			} catch (e) { // @other(unsafe)
 | 
						|
				throw thisFromOtherForThrow(e);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		getPrototypeOf(target) {
 | 
						|
			// Note: target@this(unsafe)
 | 
						|
			return thisReflectGetPrototypeOf(target);
 | 
						|
		}
 | 
						|
 | 
						|
		setPrototypeOf(target, value) {
 | 
						|
			// Note: target@this(unsafe) throws@this(unsafe)
 | 
						|
			throw new VMError(OPNA);
 | 
						|
		}
 | 
						|
 | 
						|
		apply(target, context, args) {
 | 
						|
			// Note: target@this(unsafe) context@this(unsafe) args@this(safe-array) throws@this(unsafe)
 | 
						|
			const object = this.getObject(); // @other(unsafe)
 | 
						|
			let ret; // @other(unsafe)
 | 
						|
			try {
 | 
						|
				context = otherFromThis(context);
 | 
						|
				args = otherFromThisArguments(args);
 | 
						|
				ret = otherReflectApply(object, context, args);
 | 
						|
			} catch (e) { // @other(unsafe)
 | 
						|
				throw thisFromOtherForThrow(e);
 | 
						|
			}
 | 
						|
			return thisFromOther(ret);
 | 
						|
		}
 | 
						|
 | 
						|
		construct(target, args, newTarget) {
 | 
						|
			// Note: target@this(unsafe) args@this(safe-array) newTarget@this(unsafe) throws@this(unsafe)
 | 
						|
			const object = this.getObject(); // @other(unsafe)
 | 
						|
			let ret; // @other(unsafe)
 | 
						|
			try {
 | 
						|
				args = otherFromThisArguments(args);
 | 
						|
				ret = otherReflectConstruct(object, args);
 | 
						|
			} catch (e) { // @other(unsafe)
 | 
						|
				throw thisFromOtherForThrow(e);
 | 
						|
			}
 | 
						|
			return thisFromOtherWithFactory(this.getFactory(), ret, thisFromOther(object));
 | 
						|
		}
 | 
						|
 | 
						|
		getOwnPropertyDescriptorDesc(target, prop, desc) {
 | 
						|
			// Note: target@this(unsafe) prop@prim desc@other{safe} throws@this(unsafe)
 | 
						|
			const object = this.getObject(); // @other(unsafe)
 | 
						|
			if (desc && typeof object === 'function' && (prop === 'arguments' || prop === 'caller' || prop === 'callee')) desc.value = null;
 | 
						|
			return desc;
 | 
						|
		}
 | 
						|
 | 
						|
		getOwnPropertyDescriptor(target, prop) {
 | 
						|
			// Note: target@this(unsafe) prop@prim throws@this(unsafe)
 | 
						|
			const object = this.getObject(); // @other(unsafe)
 | 
						|
			let desc; // @other(safe)
 | 
						|
			try {
 | 
						|
				desc = otherSafeGetOwnPropertyDescriptor(object, prop);
 | 
						|
			} catch (e) { // @other(unsafe)
 | 
						|
				throw thisFromOtherForThrow(e);
 | 
						|
			}
 | 
						|
 | 
						|
			desc = this.getOwnPropertyDescriptorDesc(target, prop, desc);
 | 
						|
 | 
						|
			if (!desc) return undefined;
 | 
						|
 | 
						|
			let thisDesc;
 | 
						|
			if (desc.get || desc.set) {
 | 
						|
				thisDesc = {
 | 
						|
					__proto__: null,
 | 
						|
					get: this.fromOtherWithContext(desc.get),
 | 
						|
					set: this.fromOtherWithContext(desc.set),
 | 
						|
					enumerable: desc.enumerable === true,
 | 
						|
					configurable: desc.configurable === true
 | 
						|
				};
 | 
						|
			} else {
 | 
						|
				thisDesc = {
 | 
						|
					__proto__: null,
 | 
						|
					value: this.fromOtherWithContext(desc.value),
 | 
						|
					writable: desc.writable === true,
 | 
						|
					enumerable: desc.enumerable === true,
 | 
						|
					configurable: desc.configurable === true
 | 
						|
				};
 | 
						|
			}
 | 
						|
			if (!thisDesc.configurable) {
 | 
						|
				const oldDesc = thisSafeGetOwnPropertyDescriptor(target, prop);
 | 
						|
				if (!oldDesc || oldDesc.configurable || oldDesc.writable !== thisDesc.writable) {
 | 
						|
					if (!thisReflectDefineProperty(target, prop, thisDesc)) throw thisUnexpected();
 | 
						|
				}
 | 
						|
			}
 | 
						|
			return thisDesc;
 | 
						|
		}
 | 
						|
 | 
						|
		definePropertyDesc(target, prop, desc) {
 | 
						|
			// Note: target@this(unsafe) prop@prim desc@this(safe) throws@this(unsafe)
 | 
						|
			return desc;
 | 
						|
		}
 | 
						|
 | 
						|
		defineProperty(target, prop, desc) {
 | 
						|
			// Note: target@this(unsafe) prop@prim desc@this(unsafe) throws@this(unsafe)
 | 
						|
			const object = this.getObject(); // @other(unsafe)
 | 
						|
			if (!thisReflectSetPrototypeOf(desc, null)) throw thisUnexpected();
 | 
						|
 | 
						|
			desc = this.definePropertyDesc(target, prop, desc);
 | 
						|
 | 
						|
			if (!desc) return false;
 | 
						|
 | 
						|
			let otherDesc = {__proto__: null};
 | 
						|
			let hasFunc = true;
 | 
						|
			let hasValue = true;
 | 
						|
			let hasBasic = true;
 | 
						|
			hasFunc &= otherFromThisIfAvailable(otherDesc, desc, 'get');
 | 
						|
			hasFunc &= otherFromThisIfAvailable(otherDesc, desc, 'set');
 | 
						|
			hasValue &= otherFromThisIfAvailable(otherDesc, desc, 'value');
 | 
						|
			hasValue &= otherFromThisIfAvailable(otherDesc, desc, 'writable');
 | 
						|
			hasBasic &= otherFromThisIfAvailable(otherDesc, desc, 'enumerable');
 | 
						|
			hasBasic &= otherFromThisIfAvailable(otherDesc, desc, 'configurable');
 | 
						|
 | 
						|
			try {
 | 
						|
				if (!otherReflectDefineProperty(object, prop, otherDesc)) return false;
 | 
						|
				if (otherDesc.configurable !== true && (!hasBasic || !(hasFunc || hasValue))) {
 | 
						|
					otherDesc = otherSafeGetOwnPropertyDescriptor(object, prop);
 | 
						|
				}
 | 
						|
			} catch (e) { // @other(unsafe)
 | 
						|
				throw thisFromOtherForThrow(e);
 | 
						|
			}
 | 
						|
 | 
						|
			if (!otherDesc.configurable) {
 | 
						|
				let thisDesc;
 | 
						|
				if (otherDesc.get || otherDesc.set) {
 | 
						|
					thisDesc = {
 | 
						|
						__proto__: null,
 | 
						|
						get: this.fromOtherWithContext(otherDesc.get),
 | 
						|
						set: this.fromOtherWithContext(otherDesc.set),
 | 
						|
						enumerable: otherDesc.enumerable,
 | 
						|
						configurable: otherDesc.configurable
 | 
						|
					};
 | 
						|
				} else {
 | 
						|
					thisDesc = {
 | 
						|
						__proto__: null,
 | 
						|
						value: this.fromOtherWithContext(otherDesc.value),
 | 
						|
						writable: otherDesc.writable,
 | 
						|
						enumerable: otherDesc.enumerable,
 | 
						|
						configurable: otherDesc.configurable
 | 
						|
					};
 | 
						|
				}
 | 
						|
				if (!thisReflectDefineProperty(target, prop, thisDesc)) throw thisUnexpected();
 | 
						|
			}
 | 
						|
			return true;
 | 
						|
		}
 | 
						|
 | 
						|
		deleteProperty(target, prop) {
 | 
						|
			// Note: target@this(unsafe) prop@prim throws@this(unsafe)
 | 
						|
			const object = this.getObject(); // @other(unsafe)
 | 
						|
			try {
 | 
						|
				return otherReflectDeleteProperty(object, prop) === true;
 | 
						|
			} catch (e) { // @other(unsafe)
 | 
						|
				throw thisFromOtherForThrow(e);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		has(target, key) {
 | 
						|
			// Note: target@this(unsafe) key@prim throws@this(unsafe)
 | 
						|
			const object = this.getObject(); // @other(unsafe)
 | 
						|
			try {
 | 
						|
				return otherReflectHas(object, key) === true;
 | 
						|
			} catch (e) { // @other(unsafe)
 | 
						|
				throw thisFromOtherForThrow(e);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		isExtensible(target) {
 | 
						|
			// Note: target@this(unsafe) throws@this(unsafe)
 | 
						|
			const object = this.getObject(); // @other(unsafe)
 | 
						|
			try {
 | 
						|
				if (otherReflectIsExtensible(object)) return true;
 | 
						|
			} catch (e) { // @other(unsafe)
 | 
						|
				throw thisFromOtherForThrow(e);
 | 
						|
			}
 | 
						|
			if (thisReflectIsExtensible(target)) {
 | 
						|
				this.doPreventExtensions(target, object, this);
 | 
						|
			}
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		ownKeys(target) {
 | 
						|
			// Note: target@this(unsafe) throws@this(unsafe)
 | 
						|
			const object = this.getObject(); // @other(unsafe)
 | 
						|
			let res; // @other(unsafe)
 | 
						|
			try {
 | 
						|
				res = otherReflectOwnKeys(object);
 | 
						|
			} catch (e) { // @other(unsafe)
 | 
						|
				throw thisFromOtherForThrow(e);
 | 
						|
			}
 | 
						|
			return thisFromOther(res);
 | 
						|
		}
 | 
						|
 | 
						|
		preventExtensions(target) {
 | 
						|
			// Note: target@this(unsafe) throws@this(unsafe)
 | 
						|
			const object = this.getObject(); // @other(unsafe)
 | 
						|
			try {
 | 
						|
				if (!otherReflectPreventExtensions(object)) return false;
 | 
						|
			} catch (e) { // @other(unsafe)
 | 
						|
				throw thisFromOtherForThrow(e);
 | 
						|
			}
 | 
						|
			if (thisReflectIsExtensible(target)) {
 | 
						|
				this.doPreventExtensions(target, object, this);
 | 
						|
			}
 | 
						|
			return true;
 | 
						|
		}
 | 
						|
 | 
						|
		enumerate(target) {
 | 
						|
			// Note: target@this(unsafe) throws@this(unsafe)
 | 
						|
			const object = this.getObject(); // @other(unsafe)
 | 
						|
			let res; // @other(unsafe)
 | 
						|
			try {
 | 
						|
				res = otherReflectEnumerate(object);
 | 
						|
			} catch (e) { // @other(unsafe)
 | 
						|
				throw thisFromOtherForThrow(e);
 | 
						|
			}
 | 
						|
			return this.fromOtherWithContext(res);
 | 
						|
		}
 | 
						|
 | 
						|
	}
 | 
						|
 | 
						|
	BaseHandler.prototype[thisSymbolNodeJSUtilInspectCustom] = undefined;
 | 
						|
	BaseHandler.prototype[thisSymbolToStringTag] = 'VM2 Wrapper';
 | 
						|
	BaseHandler.prototype[thisSymbolIterator] = undefined;
 | 
						|
 | 
						|
	function defaultFactory(object) {
 | 
						|
		// Note: other@other(unsafe) returns@this(unsafe) throws@this(unsafe)
 | 
						|
		return new BaseHandler(object);
 | 
						|
	}
 | 
						|
 | 
						|
	class ProtectedHandler extends BaseHandler {
 | 
						|
 | 
						|
		getFactory() {
 | 
						|
			return protectedFactory;
 | 
						|
		}
 | 
						|
 | 
						|
		set(target, key, value, receiver) {
 | 
						|
			// Note: target@this(unsafe) key@prim value@this(unsafe) receiver@this(unsafe) throws@this(unsafe)
 | 
						|
			if (typeof value === 'function') {
 | 
						|
				return thisReflectDefineProperty(receiver, key, {
 | 
						|
					__proto__: null,
 | 
						|
					value: value,
 | 
						|
					writable: true,
 | 
						|
					enumerable: true,
 | 
						|
					configurable: true
 | 
						|
				}) === true;
 | 
						|
			}
 | 
						|
			return super.set(target, key, value, receiver);
 | 
						|
		}
 | 
						|
 | 
						|
		definePropertyDesc(target, prop, desc) {
 | 
						|
			// Note: target@this(unsafe) prop@prim desc@this(safe) throws@this(unsafe)
 | 
						|
			if (desc && (desc.set || desc.get || typeof desc.value === 'function')) return undefined;
 | 
						|
			return desc;
 | 
						|
		}
 | 
						|
 | 
						|
	}
 | 
						|
 | 
						|
	function protectedFactory(object) {
 | 
						|
		// Note: other@other(unsafe) returns@this(unsafe) throws@this(unsafe)
 | 
						|
		return new ProtectedHandler(object);
 | 
						|
	}
 | 
						|
 | 
						|
	class ReadOnlyHandler extends BaseHandler {
 | 
						|
 | 
						|
		getFactory() {
 | 
						|
			return readonlyFactory;
 | 
						|
		}
 | 
						|
 | 
						|
		set(target, key, value, receiver) {
 | 
						|
			// Note: target@this(unsafe) key@prim value@this(unsafe) receiver@this(unsafe) throws@this(unsafe)
 | 
						|
			return thisReflectDefineProperty(receiver, key, {
 | 
						|
				__proto__: null,
 | 
						|
				value: value,
 | 
						|
				writable: true,
 | 
						|
				enumerable: true,
 | 
						|
				configurable: true
 | 
						|
			});
 | 
						|
		}
 | 
						|
 | 
						|
		setPrototypeOf(target, value) {
 | 
						|
			// Note: target@this(unsafe) throws@this(unsafe)
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		defineProperty(target, prop, desc) {
 | 
						|
			// Note: target@this(unsafe) prop@prim desc@this(unsafe) throws@this(unsafe)
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		deleteProperty(target, prop) {
 | 
						|
			// Note: target@this(unsafe) prop@prim throws@this(unsafe)
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		isExtensible(target) {
 | 
						|
			// Note: target@this(unsafe) throws@this(unsafe)
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		preventExtensions(target) {
 | 
						|
			// Note: target@this(unsafe) throws@this(unsafe)
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
	}
 | 
						|
 | 
						|
	function readonlyFactory(object) {
 | 
						|
		// Note: other@other(unsafe) returns@this(unsafe) throws@this(unsafe)
 | 
						|
		return new ReadOnlyHandler(object);
 | 
						|
	}
 | 
						|
 | 
						|
	class ReadOnlyMockHandler extends ReadOnlyHandler {
 | 
						|
 | 
						|
		constructor(object, mock) {
 | 
						|
			// Note: object@other(unsafe) mock:this(unsafe) throws@this(unsafe)
 | 
						|
			super(object);
 | 
						|
			this.mock = mock;
 | 
						|
		}
 | 
						|
 | 
						|
		get(target, key, receiver) {
 | 
						|
			// Note: target@this(unsafe) key@prim receiver@this(unsafe) throws@this(unsafe)
 | 
						|
			const object = this.getObject(); // @other(unsafe)
 | 
						|
			const mock = this.mock;
 | 
						|
			if (thisReflectApply(thisObjectHasOwnProperty, mock, key) && !thisOtherHasOwnProperty(object, key)) {
 | 
						|
				return mock[key];
 | 
						|
			}
 | 
						|
			return super.get(target, key, receiver);
 | 
						|
		}
 | 
						|
 | 
						|
	}
 | 
						|
 | 
						|
	function thisFromOther(other) {
 | 
						|
		// Note: other@other(unsafe) returns@this(unsafe) throws@this(unsafe)
 | 
						|
		return thisFromOtherWithFactory(defaultFactory, other);
 | 
						|
	}
 | 
						|
 | 
						|
	function thisProxyOther(factory, other, proto) {
 | 
						|
		const target = thisCreateTargetObject(other, proto);
 | 
						|
		const handler = factory(other);
 | 
						|
		const proxy = new ThisProxy(target, handler);
 | 
						|
		try {
 | 
						|
			otherReflectApply(otherWeakMapSet, mappingThisToOther, [proxy, other]);
 | 
						|
			registerProxy(proxy, handler);
 | 
						|
		} catch (e) {
 | 
						|
			throw new VMError('Unexpected error');
 | 
						|
		}
 | 
						|
		if (!isHost) {
 | 
						|
			thisReflectApply(thisWeakMapSet, mappingOtherToThis, [other, proxy]);
 | 
						|
			return proxy;
 | 
						|
		}
 | 
						|
		const proxy2 = new ThisProxy(proxy, emptyForzenObject);
 | 
						|
		try {
 | 
						|
			otherReflectApply(otherWeakMapSet, mappingThisToOther, [proxy2, other]);
 | 
						|
			registerProxy(proxy2, handler);
 | 
						|
		} catch (e) {
 | 
						|
			throw new VMError('Unexpected error');
 | 
						|
		}
 | 
						|
		thisReflectApply(thisWeakMapSet, mappingOtherToThis, [other, proxy2]);
 | 
						|
		return proxy2;
 | 
						|
	}
 | 
						|
 | 
						|
	function thisEnsureThis(other) {
 | 
						|
		const type = typeof other;
 | 
						|
		switch (type) {
 | 
						|
			case 'object':
 | 
						|
				if (other === null) {
 | 
						|
					return null;
 | 
						|
				}
 | 
						|
				// fallthrough
 | 
						|
			case 'function':
 | 
						|
				let proto = thisReflectGetPrototypeOf(other);
 | 
						|
				if (!proto) {
 | 
						|
					return other;
 | 
						|
				}
 | 
						|
				while (proto) {
 | 
						|
					const mapping = thisReflectApply(thisMapGet, protoMappings, [proto]);
 | 
						|
					if (mapping) {
 | 
						|
						const mapped = thisReflectApply(thisWeakMapGet, mappingOtherToThis, [other]);
 | 
						|
						if (mapped) return mapped;
 | 
						|
						return mapping(defaultFactory, other);
 | 
						|
					}
 | 
						|
					proto = thisReflectGetPrototypeOf(proto);
 | 
						|
				}
 | 
						|
				return other;
 | 
						|
			case 'undefined':
 | 
						|
			case 'string':
 | 
						|
			case 'number':
 | 
						|
			case 'boolean':
 | 
						|
			case 'symbol':
 | 
						|
			case 'bigint':
 | 
						|
				return other;
 | 
						|
 | 
						|
			default: // new, unknown types can be dangerous
 | 
						|
				throw new VMError(`Unknown type '${type}'`);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	function thisFromOtherForThrow(other) {
 | 
						|
		for (let loop = 0; loop < 10; loop++) {
 | 
						|
			const type = typeof other;
 | 
						|
			switch (type) {
 | 
						|
				case 'object':
 | 
						|
					if (other === null) {
 | 
						|
						return null;
 | 
						|
					}
 | 
						|
					// fallthrough
 | 
						|
				case 'function':
 | 
						|
					const mapped = thisReflectApply(thisWeakMapGet, mappingOtherToThis, [other]);
 | 
						|
					if (mapped) return mapped;
 | 
						|
					let proto;
 | 
						|
					try {
 | 
						|
						proto = otherReflectGetPrototypeOf(other);
 | 
						|
					} catch (e) { // @other(unsafe)
 | 
						|
						other = e;
 | 
						|
						break;
 | 
						|
					}
 | 
						|
					if (!proto) {
 | 
						|
						return thisProxyOther(defaultFactory, other, null);
 | 
						|
					}
 | 
						|
					for (;;) {
 | 
						|
						const mapping = thisReflectApply(thisMapGet, protoMappings, [proto]);
 | 
						|
						if (mapping) return mapping(defaultFactory, other);
 | 
						|
						try {
 | 
						|
							proto = otherReflectGetPrototypeOf(proto);
 | 
						|
						} catch (e) { // @other(unsafe)
 | 
						|
							other = e;
 | 
						|
							break;
 | 
						|
						}
 | 
						|
						if (!proto) return thisProxyOther(defaultFactory, other, thisObjectPrototype);
 | 
						|
					}
 | 
						|
					break;
 | 
						|
				case 'undefined':
 | 
						|
				case 'string':
 | 
						|
				case 'number':
 | 
						|
				case 'boolean':
 | 
						|
				case 'symbol':
 | 
						|
				case 'bigint':
 | 
						|
					return other;
 | 
						|
 | 
						|
				default: // new, unknown types can be dangerous
 | 
						|
					throw new VMError(`Unknown type '${type}'`);
 | 
						|
			}
 | 
						|
		}
 | 
						|
		throw new VMError('Exception recursion depth');
 | 
						|
	}
 | 
						|
 | 
						|
	function thisFromOtherWithFactory(factory, other, proto) {
 | 
						|
		const type = typeof other;
 | 
						|
		switch (type) {
 | 
						|
			case 'object':
 | 
						|
				if (other === null) {
 | 
						|
					return null;
 | 
						|
				}
 | 
						|
				// fallthrough
 | 
						|
			case 'function':
 | 
						|
				const mapped = thisReflectApply(thisWeakMapGet, mappingOtherToThis, [other]);
 | 
						|
				if (mapped) return mapped;
 | 
						|
				if (proto) {
 | 
						|
					return thisProxyOther(factory, other, proto);
 | 
						|
				}
 | 
						|
				try {
 | 
						|
					proto = otherReflectGetPrototypeOf(other);
 | 
						|
				} catch (e) { // @other(unsafe)
 | 
						|
					throw thisFromOtherForThrow(e);
 | 
						|
				}
 | 
						|
				if (!proto) {
 | 
						|
					return thisProxyOther(factory, other, null);
 | 
						|
				}
 | 
						|
				do {
 | 
						|
					const mapping = thisReflectApply(thisMapGet, protoMappings, [proto]);
 | 
						|
					if (mapping) return mapping(factory, other);
 | 
						|
					try {
 | 
						|
						proto = otherReflectGetPrototypeOf(proto);
 | 
						|
					} catch (e) { // @other(unsafe)
 | 
						|
						throw thisFromOtherForThrow(e);
 | 
						|
					}
 | 
						|
				} while (proto);
 | 
						|
				return thisProxyOther(factory, other, thisObjectPrototype);
 | 
						|
			case 'undefined':
 | 
						|
			case 'string':
 | 
						|
			case 'number':
 | 
						|
			case 'boolean':
 | 
						|
			case 'symbol':
 | 
						|
			case 'bigint':
 | 
						|
				return other;
 | 
						|
 | 
						|
			default: // new, unknown types can be dangerous
 | 
						|
				throw new VMError(`Unknown type '${type}'`);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	function thisFromOtherArguments(args) {
 | 
						|
		// Note: args@other(safe-array) returns@this(safe-array) throws@this(unsafe)
 | 
						|
		const arr = [];
 | 
						|
		for (let i = 0; i < args.length; i++) {
 | 
						|
			const value = thisFromOther(args[i]);
 | 
						|
			thisReflectDefineProperty(arr, i, {
 | 
						|
				__proto__: null,
 | 
						|
				value: value,
 | 
						|
				writable: true,
 | 
						|
				enumerable: true,
 | 
						|
				configurable: true
 | 
						|
			});
 | 
						|
		}
 | 
						|
		return arr;
 | 
						|
	}
 | 
						|
 | 
						|
	function thisConnect(obj, other) {
 | 
						|
		// Note: obj@this(unsafe) other@other(unsafe) throws@this(unsafe)
 | 
						|
		try {
 | 
						|
			otherReflectApply(otherWeakMapSet, mappingThisToOther, [obj, other]);
 | 
						|
		} catch (e) {
 | 
						|
			throw new VMError('Unexpected error');
 | 
						|
		}
 | 
						|
		thisReflectApply(thisWeakMapSet, mappingOtherToThis, [other, obj]);
 | 
						|
	}
 | 
						|
 | 
						|
	thisAddProtoMapping(thisGlobalPrototypes.Object, otherGlobalPrototypes.Object);
 | 
						|
	thisAddProtoMapping(thisGlobalPrototypes.Array, otherGlobalPrototypes.Array);
 | 
						|
 | 
						|
	for (let i = 0; i < globalsList.length; i++) {
 | 
						|
		const key = globalsList[i];
 | 
						|
		const tp = thisGlobalPrototypes[key];
 | 
						|
		const op = otherGlobalPrototypes[key];
 | 
						|
		if (tp && op) thisAddProtoMapping(tp, op, key);
 | 
						|
	}
 | 
						|
 | 
						|
	for (let i = 0; i < errorsList.length; i++) {
 | 
						|
		const key = errorsList[i];
 | 
						|
		const tp = thisGlobalPrototypes[key];
 | 
						|
		const op = otherGlobalPrototypes[key];
 | 
						|
		if (tp && op) thisAddProtoMapping(tp, op, 'Error');
 | 
						|
	}
 | 
						|
 | 
						|
	thisAddProtoMapping(thisGlobalPrototypes.VMError, otherGlobalPrototypes.VMError, 'Error');
 | 
						|
 | 
						|
	result.BaseHandler = BaseHandler;
 | 
						|
	result.ProtectedHandler = ProtectedHandler;
 | 
						|
	result.ReadOnlyHandler = ReadOnlyHandler;
 | 
						|
	result.ReadOnlyMockHandler = ReadOnlyMockHandler;
 | 
						|
 | 
						|
	return result;
 | 
						|
}
 | 
						|
 | 
						|
exports.createBridge = createBridge;
 | 
						|
exports.VMError = VMError;
 |