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.
		
		
		
		
		
			
		
			
				
					978 lines
				
				28 KiB
			
		
		
			
		
	
	
					978 lines
				
				28 KiB
			| 
											3 years ago
										 | // Copyright Joyent, Inc. and other Node contributors.
 | ||
|  | //
 | ||
|  | // Permission is hereby granted, free of charge, to any person obtaining a
 | ||
|  | // copy of this software and associated documentation files (the
 | ||
|  | // "Software"), to deal in the Software without restriction, including
 | ||
|  | // without limitation the rights to use, copy, modify, merge, publish,
 | ||
|  | // distribute, sublicense, and/or sell copies of the Software, and to permit
 | ||
|  | // persons to whom the Software is furnished to do so, subject to the
 | ||
|  | // following conditions:
 | ||
|  | //
 | ||
|  | // The above copyright notice and this permission notice shall be included
 | ||
|  | // in all copies or substantial portions of the Software.
 | ||
|  | //
 | ||
|  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | ||
|  | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | ||
|  | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
 | ||
|  | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 | ||
|  | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 | ||
|  | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 | ||
|  | // USE OR OTHER DEALINGS IN THE SOFTWARE.
 | ||
|  | 
 | ||
|  | // Modified by the vm2 team to make this a standalone module to be loaded into the sandbox.
 | ||
|  | 
 | ||
|  | 'use strict'; | ||
|  | 
 | ||
|  | const host = fromhost; | ||
|  | 
 | ||
|  | const { | ||
|  | 	Boolean, | ||
|  |   Error, | ||
|  | 	String, | ||
|  | 	Symbol | ||
|  | } = globalThis; | ||
|  | 
 | ||
|  | const ReflectApply = Reflect.apply; | ||
|  | const ReflectOwnKeys = Reflect.ownKeys; | ||
|  | 
 | ||
|  | const ErrorCaptureStackTrace = Error.captureStackTrace; | ||
|  | 
 | ||
|  | const NumberIsNaN = Number.isNaN; | ||
|  | 
 | ||
|  | const ObjectCreate = Object.create; | ||
|  | const ObjectDefineProperty = Object.defineProperty; | ||
|  | const ObjectDefineProperties = Object.defineProperties; | ||
|  | const ObjectGetPrototypeOf = Object.getPrototypeOf; | ||
|  | 
 | ||
|  | const SymbolFor = Symbol.for; | ||
|  | 
 | ||
|  | function uncurryThis(func) { | ||
|  | 	return (thiz, ...args) => ReflectApply(func, thiz, args); | ||
|  | } | ||
|  | 
 | ||
|  | const ArrayPrototypeIndexOf = uncurryThis(Array.prototype.indexOf); | ||
|  | const ArrayPrototypeJoin = uncurryThis(Array.prototype.join); | ||
|  | const ArrayPrototypeSlice = uncurryThis(Array.prototype.slice); | ||
|  | const ArrayPrototypeSplice = uncurryThis(Array.prototype.splice); | ||
|  | const ArrayPrototypeUnshift = uncurryThis(Array.prototype.unshift); | ||
|  | 
 | ||
|  | const kRejection = SymbolFor('nodejs.rejection'); | ||
|  | 
 | ||
|  | function inspect(obj) { | ||
|  | 	return typeof obj === 'symbol' ? obj.toString() : `${obj}`; | ||
|  | } | ||
|  | 
 | ||
|  | function spliceOne(list, index) { | ||
|  | 	for (; index + 1 < list.length; index++) | ||
|  | 		list[index] = list[index + 1]; | ||
|  | 	list.pop(); | ||
|  | } | ||
|  | 
 | ||
|  | function assert(what, message) { | ||
|  | 	if (!what) throw new Error(message); | ||
|  | } | ||
|  | 
 | ||
|  | function E(key, msg, Base) { | ||
|  | 	return function NodeError(...args) { | ||
|  | 	  const error = new Base(); | ||
|  | 	  const message = ReflectApply(msg, error, args); | ||
|  | 	  ObjectDefineProperties(error, { | ||
|  | 		message: { | ||
|  | 		  value: message, | ||
|  | 		  enumerable: false, | ||
|  | 		  writable: true, | ||
|  | 		  configurable: true, | ||
|  | 		}, | ||
|  | 		toString: { | ||
|  | 		  value() { | ||
|  | 			return `${this.name} [${key}]: ${this.message}`; | ||
|  | 		  }, | ||
|  | 		  enumerable: false, | ||
|  | 		  writable: true, | ||
|  | 		  configurable: true, | ||
|  | 		}, | ||
|  | 	  }); | ||
|  | 	  error.code = key; | ||
|  | 	  return error; | ||
|  | 	}; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | const ERR_INVALID_ARG_TYPE = E('ERR_INVALID_ARG_TYPE', | ||
|  |   (name, expected, actual) => { | ||
|  |     assert(typeof name === 'string', "'name' must be a string"); | ||
|  |     if (!ArrayIsArray(expected)) { | ||
|  |       expected = [expected]; | ||
|  |     } | ||
|  | 
 | ||
|  |     let msg = 'The '; | ||
|  |     if (StringPrototypeEndsWith(name, ' argument')) { | ||
|  |       // For cases like 'first argument'
 | ||
|  |       msg += `${name} `; | ||
|  |     } else { | ||
|  |       const type = StringPrototypeIncludes(name, '.') ? 'property' : 'argument'; | ||
|  |       msg += `"${name}" ${type} `; | ||
|  |     } | ||
|  |     msg += 'must be '; | ||
|  | 
 | ||
|  |     const types = []; | ||
|  |     const instances = []; | ||
|  |     const other = []; | ||
|  | 
 | ||
|  |     for (const value of expected) { | ||
|  |       assert(typeof value === 'string', | ||
|  |              'All expected entries have to be of type string'); | ||
|  |       if (ArrayPrototypeIncludes(kTypes, value)) { | ||
|  |         ArrayPrototypePush(types, StringPrototypeToLowerCase(value)); | ||
|  |       } else if (RegExpPrototypeTest(classRegExp, value)) { | ||
|  |         ArrayPrototypePush(instances, value); | ||
|  |       } else { | ||
|  |         assert(value !== 'object', | ||
|  |                'The value "object" should be written as "Object"'); | ||
|  |         ArrayPrototypePush(other, value); | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     // Special handle `object` in case other instances are allowed to outline
 | ||
|  |     // the differences between each other.
 | ||
|  |     if (instances.length > 0) { | ||
|  |       const pos = ArrayPrototypeIndexOf(types, 'object'); | ||
|  |       if (pos !== -1) { | ||
|  |         ArrayPrototypeSplice(types, pos, 1); | ||
|  |         ArrayPrototypePush(instances, 'Object'); | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     if (types.length > 0) { | ||
|  |       if (types.length > 2) { | ||
|  |         const last = ArrayPrototypePop(types); | ||
|  |         msg += `one of type ${ArrayPrototypeJoin(types, ', ')}, or ${last}`; | ||
|  |       } else if (types.length === 2) { | ||
|  |         msg += `one of type ${types[0]} or ${types[1]}`; | ||
|  |       } else { | ||
|  |         msg += `of type ${types[0]}`; | ||
|  |       } | ||
|  |       if (instances.length > 0 || other.length > 0) | ||
|  |         msg += ' or '; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (instances.length > 0) { | ||
|  |       if (instances.length > 2) { | ||
|  |         const last = ArrayPrototypePop(instances); | ||
|  |         msg += | ||
|  |           `an instance of ${ArrayPrototypeJoin(instances, ', ')}, or ${last}`; | ||
|  |       } else { | ||
|  |         msg += `an instance of ${instances[0]}`; | ||
|  |         if (instances.length === 2) { | ||
|  |           msg += ` or ${instances[1]}`; | ||
|  |         } | ||
|  |       } | ||
|  |       if (other.length > 0) | ||
|  |         msg += ' or '; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (other.length > 0) { | ||
|  |       if (other.length > 2) { | ||
|  |         const last = ArrayPrototypePop(other); | ||
|  |         msg += `one of ${ArrayPrototypeJoin(other, ', ')}, or ${last}`; | ||
|  |       } else if (other.length === 2) { | ||
|  |         msg += `one of ${other[0]} or ${other[1]}`; | ||
|  |       } else { | ||
|  |         if (StringPrototypeToLowerCase(other[0]) !== other[0]) | ||
|  |           msg += 'an '; | ||
|  |         msg += `${other[0]}`; | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     if (actual == null) { | ||
|  |       msg += `. Received ${actual}`; | ||
|  |     } else if (typeof actual === 'function' && actual.name) { | ||
|  |       msg += `. Received function ${actual.name}`; | ||
|  |     } else if (typeof actual === 'object') { | ||
|  |       if (actual.constructor && actual.constructor.name) { | ||
|  |         msg += `. Received an instance of ${actual.constructor.name}`; | ||
|  |       } else { | ||
|  |         const inspected = inspect(actual, { depth: -1 }); | ||
|  |         msg += `. Received ${inspected}`; | ||
|  |       } | ||
|  |     } else { | ||
|  |       let inspected = inspect(actual, { colors: false }); | ||
|  |       if (inspected.length > 25) | ||
|  |         inspected = `${StringPrototypeSlice(inspected, 0, 25)}...`; | ||
|  |       msg += `. Received type ${typeof actual} (${inspected})`; | ||
|  |     } | ||
|  |     return msg; | ||
|  |   }, TypeError); | ||
|  | 
 | ||
|  | const ERR_INVALID_THIS = E('ERR_INVALID_THIS', s => `Value of "this" must be of type ${s}`, TypeError); | ||
|  | 
 | ||
|  | const ERR_OUT_OF_RANGE = E('ERR_OUT_OF_RANGE', | ||
|  |   (str, range, input, replaceDefaultBoolean = false) => { | ||
|  |     assert(range, 'Missing "range" argument'); | ||
|  |     let msg = replaceDefaultBoolean ? str : | ||
|  |       `The value of "${str}" is out of range.`; | ||
|  |     const received = inspect(input); | ||
|  |     msg += ` It must be ${range}. Received ${received}`; | ||
|  |     return msg; | ||
|  |   }, RangeError); | ||
|  | 
 | ||
|  | const ERR_UNHANDLED_ERROR = E('ERR_UNHANDLED_ERROR', | ||
|  |   err => { | ||
|  |     const msg = 'Unhandled error.'; | ||
|  |     if (err === undefined) return msg; | ||
|  |     return `${msg} (${err})`; | ||
|  |   }, Error); | ||
|  | 
 | ||
|  | function validateBoolean(value, name) { | ||
|  |   if (typeof value !== 'boolean') | ||
|  |     throw new ERR_INVALID_ARG_TYPE(name, 'boolean', value); | ||
|  | } | ||
|  | 
 | ||
|  | function validateFunction(value, name) { | ||
|  |   if (typeof value !== 'function') | ||
|  |     throw new ERR_INVALID_ARG_TYPE(name, 'Function', value); | ||
|  | } | ||
|  | 
 | ||
|  | function validateString(value, name) { | ||
|  |   if (typeof value !== 'string') | ||
|  |     throw new ERR_INVALID_ARG_TYPE(name, 'string', value); | ||
|  | } | ||
|  | 
 | ||
|  | function nc(cond, e) { | ||
|  | 	return cond === undefined || cond === null ? e : cond; | ||
|  | } | ||
|  | 
 | ||
|  | function oc(base, key) { | ||
|  | 	return base === undefined || base === null ? undefined : base[key]; | ||
|  | } | ||
|  | 
 | ||
|  | const kCapture = Symbol('kCapture'); | ||
|  | const kErrorMonitor = host.kErrorMonitor || Symbol('events.errorMonitor'); | ||
|  | const kMaxEventTargetListeners = Symbol('events.maxEventTargetListeners'); | ||
|  | const kMaxEventTargetListenersWarned = | ||
|  |   Symbol('events.maxEventTargetListenersWarned'); | ||
|  | 
 | ||
|  | const kIsEventTarget = SymbolFor('nodejs.event_target'); | ||
|  | 
 | ||
|  | function isEventTarget(obj) { | ||
|  | 	return oc(oc(obj, 'constructor'), kIsEventTarget); | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Creates a new `EventEmitter` instance. | ||
|  |  * @param {{ captureRejections?: boolean; }} [opts] | ||
|  |  * @constructs {EventEmitter} | ||
|  |  */ | ||
|  | function EventEmitter(opts) { | ||
|  |   EventEmitter.init.call(this, opts); | ||
|  | } | ||
|  | module.exports = EventEmitter; | ||
|  | if (host.once) module.exports.once = host.once; | ||
|  | if (host.on) module.exports.on = host.on; | ||
|  | if (host.getEventListeners) module.exports.getEventListeners = host.getEventListeners; | ||
|  | // Backwards-compat with node 0.10.x
 | ||
|  | EventEmitter.EventEmitter = EventEmitter; | ||
|  | 
 | ||
|  | EventEmitter.usingDomains = false; | ||
|  | 
 | ||
|  | EventEmitter.captureRejectionSymbol = kRejection; | ||
|  | ObjectDefineProperty(EventEmitter, 'captureRejections', { | ||
|  |   get() { | ||
|  |     return EventEmitter.prototype[kCapture]; | ||
|  |   }, | ||
|  |   set(value) { | ||
|  |     validateBoolean(value, 'EventEmitter.captureRejections'); | ||
|  | 
 | ||
|  |     EventEmitter.prototype[kCapture] = value; | ||
|  |   }, | ||
|  |   enumerable: true | ||
|  | }); | ||
|  | 
 | ||
|  | if (host.EventEmitterReferencingAsyncResource) { | ||
|  | 	const kAsyncResource = Symbol('kAsyncResource'); | ||
|  | 	const EventEmitterReferencingAsyncResource = host.EventEmitterReferencingAsyncResource; | ||
|  | 
 | ||
|  | 	class EventEmitterAsyncResource extends EventEmitter { | ||
|  | 		/** | ||
|  | 		 * @param {{ | ||
|  | 		 *   name?: string, | ||
|  | 		 *   triggerAsyncId?: number, | ||
|  | 		 *   requireManualDestroy?: boolean, | ||
|  | 		 * }} [options] | ||
|  | 		 */ | ||
|  | 		constructor(options = undefined) { | ||
|  | 			let name; | ||
|  | 			if (typeof options === 'string') { | ||
|  | 				name = options; | ||
|  | 				options = undefined; | ||
|  | 			} else { | ||
|  | 				if (new.target === EventEmitterAsyncResource) { | ||
|  | 					validateString(oc(options, 'name'), 'options.name'); | ||
|  | 				} | ||
|  | 				name = oc(options, 'name') || new.target.name; | ||
|  | 			} | ||
|  | 			super(options); | ||
|  | 
 | ||
|  | 			this[kAsyncResource] = | ||
|  | 				new EventEmitterReferencingAsyncResource(this, name, options); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		/** | ||
|  | 		 * @param {symbol,string} event | ||
|  | 		 * @param  {...any} args | ||
|  | 		 * @returns {boolean} | ||
|  | 		 */ | ||
|  | 		emit(event, ...args) { | ||
|  | 			if (this[kAsyncResource] === undefined) | ||
|  | 				throw new ERR_INVALID_THIS('EventEmitterAsyncResource'); | ||
|  | 			const { asyncResource } = this; | ||
|  | 			ArrayPrototypeUnshift(args, super.emit, this, event); | ||
|  | 			return ReflectApply(asyncResource.runInAsyncScope, asyncResource, | ||
|  | 													args); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		/** | ||
|  | 		 * @returns {void} | ||
|  | 		 */ | ||
|  | 		emitDestroy() { | ||
|  | 			if (this[kAsyncResource] === undefined) | ||
|  | 				throw new ERR_INVALID_THIS('EventEmitterAsyncResource'); | ||
|  | 			this.asyncResource.emitDestroy(); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		/** | ||
|  | 		 * @type {number} | ||
|  | 		 */ | ||
|  | 		get asyncId() { | ||
|  | 			if (this[kAsyncResource] === undefined) | ||
|  | 				throw new ERR_INVALID_THIS('EventEmitterAsyncResource'); | ||
|  | 			return this.asyncResource.asyncId(); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		/** | ||
|  | 		 * @type {number} | ||
|  | 		 */ | ||
|  | 		get triggerAsyncId() { | ||
|  | 			if (this[kAsyncResource] === undefined) | ||
|  | 				throw new ERR_INVALID_THIS('EventEmitterAsyncResource'); | ||
|  | 			return this.asyncResource.triggerAsyncId(); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		/** | ||
|  | 		 * @type {EventEmitterReferencingAsyncResource} | ||
|  | 		 */ | ||
|  | 		get asyncResource() { | ||
|  | 			if (this[kAsyncResource] === undefined) | ||
|  | 				throw new ERR_INVALID_THIS('EventEmitterAsyncResource'); | ||
|  | 			return this[kAsyncResource]; | ||
|  | 		} | ||
|  | 	} | ||
|  | 	EventEmitter.EventEmitterAsyncResource = EventEmitterAsyncResource; | ||
|  | } | ||
|  | 
 | ||
|  | EventEmitter.errorMonitor = kErrorMonitor; | ||
|  | 
 | ||
|  | // The default for captureRejections is false
 | ||
|  | ObjectDefineProperty(EventEmitter.prototype, kCapture, { | ||
|  |   value: false, | ||
|  |   writable: true, | ||
|  |   enumerable: false | ||
|  | }); | ||
|  | 
 | ||
|  | EventEmitter.prototype._events = undefined; | ||
|  | EventEmitter.prototype._eventsCount = 0; | ||
|  | EventEmitter.prototype._maxListeners = undefined; | ||
|  | 
 | ||
|  | // By default EventEmitters will print a warning if more than 10 listeners are
 | ||
|  | // added to it. This is a useful default which helps finding memory leaks.
 | ||
|  | let defaultMaxListeners = 10; | ||
|  | 
 | ||
|  | function checkListener(listener) { | ||
|  |   validateFunction(listener, 'listener'); | ||
|  | } | ||
|  | 
 | ||
|  | ObjectDefineProperty(EventEmitter, 'defaultMaxListeners', { | ||
|  |   enumerable: true, | ||
|  |   get: function() { | ||
|  |     return defaultMaxListeners; | ||
|  |   }, | ||
|  |   set: function(arg) { | ||
|  |     if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) { | ||
|  |       throw new ERR_OUT_OF_RANGE('defaultMaxListeners', | ||
|  |                                  'a non-negative number', | ||
|  |                                  arg); | ||
|  |     } | ||
|  |     defaultMaxListeners = arg; | ||
|  |   } | ||
|  | }); | ||
|  | 
 | ||
|  | ObjectDefineProperties(EventEmitter, { | ||
|  |   kMaxEventTargetListeners: { | ||
|  |     value: kMaxEventTargetListeners, | ||
|  |     enumerable: false, | ||
|  |     configurable: false, | ||
|  |     writable: false, | ||
|  |   }, | ||
|  |   kMaxEventTargetListenersWarned: { | ||
|  |     value: kMaxEventTargetListenersWarned, | ||
|  |     enumerable: false, | ||
|  |     configurable: false, | ||
|  |     writable: false, | ||
|  |   } | ||
|  | }); | ||
|  | 
 | ||
|  | /** | ||
|  |  * Sets the max listeners. | ||
|  |  * @param {number} n | ||
|  |  * @param {EventTarget[] | EventEmitter[]} [eventTargets] | ||
|  |  * @returns {void} | ||
|  |  */ | ||
|  | EventEmitter.setMaxListeners = | ||
|  |   function(n = defaultMaxListeners, ...eventTargets) { | ||
|  |     if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) | ||
|  |       throw new ERR_OUT_OF_RANGE('n', 'a non-negative number', n); | ||
|  |     if (eventTargets.length === 0) { | ||
|  |       defaultMaxListeners = n; | ||
|  |     } else { | ||
|  |       for (let i = 0; i < eventTargets.length; i++) { | ||
|  |         const target = eventTargets[i]; | ||
|  |         if (isEventTarget(target)) { | ||
|  |           target[kMaxEventTargetListeners] = n; | ||
|  |           target[kMaxEventTargetListenersWarned] = false; | ||
|  |         } else if (typeof target.setMaxListeners === 'function') { | ||
|  |           target.setMaxListeners(n); | ||
|  |         } else { | ||
|  |           throw new ERR_INVALID_ARG_TYPE( | ||
|  |             'eventTargets', | ||
|  |             ['EventEmitter', 'EventTarget'], | ||
|  |             target); | ||
|  |         } | ||
|  |       } | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  | // If you're updating this function definition, please also update any
 | ||
|  | // re-definitions, such as the one in the Domain module (lib/domain.js).
 | ||
|  | EventEmitter.init = function(opts) { | ||
|  | 
 | ||
|  |   if (this._events === undefined || | ||
|  |       this._events === ObjectGetPrototypeOf(this)._events) { | ||
|  |     this._events = ObjectCreate(null); | ||
|  |     this._eventsCount = 0; | ||
|  |   } | ||
|  | 
 | ||
|  |   this._maxListeners = this._maxListeners || undefined; | ||
|  | 
 | ||
|  | 
 | ||
|  |   if (oc(opts, 'captureRejections')) { | ||
|  |     validateBoolean(opts.captureRejections, 'options.captureRejections'); | ||
|  |     this[kCapture] = Boolean(opts.captureRejections); | ||
|  |   } else { | ||
|  |     // Assigning the kCapture property directly saves an expensive
 | ||
|  |     // prototype lookup in a very sensitive hot path.
 | ||
|  |     this[kCapture] = EventEmitter.prototype[kCapture]; | ||
|  |   } | ||
|  | }; | ||
|  | 
 | ||
|  | function addCatch(that, promise, type, args) { | ||
|  |   if (!that[kCapture]) { | ||
|  |     return; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Handle Promises/A+ spec, then could be a getter
 | ||
|  |   // that throws on second use.
 | ||
|  |   try { | ||
|  |     const then = promise.then; | ||
|  | 
 | ||
|  |     if (typeof then === 'function') { | ||
|  |       then.call(promise, undefined, function(err) { | ||
|  |         // The callback is called with nextTick to avoid a follow-up
 | ||
|  |         // rejection from this promise.
 | ||
|  |         process.nextTick(emitUnhandledRejectionOrErr, that, err, type, args); | ||
|  |       }); | ||
|  |     } | ||
|  |   } catch (err) { | ||
|  |     that.emit('error', err); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | function emitUnhandledRejectionOrErr(ee, err, type, args) { | ||
|  |   if (typeof ee[kRejection] === 'function') { | ||
|  |     ee[kRejection](err, type, ...args); | ||
|  |   } else { | ||
|  |     // We have to disable the capture rejections mechanism, otherwise
 | ||
|  |     // we might end up in an infinite loop.
 | ||
|  |     const prev = ee[kCapture]; | ||
|  | 
 | ||
|  |     // If the error handler throws, it is not catchable and it
 | ||
|  |     // will end up in 'uncaughtException'. We restore the previous
 | ||
|  |     // value of kCapture in case the uncaughtException is present
 | ||
|  |     // and the exception is handled.
 | ||
|  |     try { | ||
|  |       ee[kCapture] = false; | ||
|  |       ee.emit('error', err); | ||
|  |     } finally { | ||
|  |       ee[kCapture] = prev; | ||
|  |     } | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Increases the max listeners of the event emitter. | ||
|  |  * @param {number} n | ||
|  |  * @returns {EventEmitter} | ||
|  |  */ | ||
|  | EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { | ||
|  |   if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) { | ||
|  |     throw new ERR_OUT_OF_RANGE('n', 'a non-negative number', n); | ||
|  |   } | ||
|  |   this._maxListeners = n; | ||
|  |   return this; | ||
|  | }; | ||
|  | 
 | ||
|  | function _getMaxListeners(that) { | ||
|  |   if (that._maxListeners === undefined) | ||
|  |     return EventEmitter.defaultMaxListeners; | ||
|  |   return that._maxListeners; | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the current max listener value for the event emitter. | ||
|  |  * @returns {number} | ||
|  |  */ | ||
|  | EventEmitter.prototype.getMaxListeners = function getMaxListeners() { | ||
|  |   return _getMaxListeners(this); | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Synchronously calls each of the listeners registered | ||
|  |  * for the event. | ||
|  |  * @param {string | symbol} type | ||
|  |  * @param {...any} [args] | ||
|  |  * @returns {boolean} | ||
|  |  */ | ||
|  | EventEmitter.prototype.emit = function emit(type, ...args) { | ||
|  |   let doError = (type === 'error'); | ||
|  | 
 | ||
|  |   const events = this._events; | ||
|  |   if (events !== undefined) { | ||
|  |     if (doError && events[kErrorMonitor] !== undefined) | ||
|  |       this.emit(kErrorMonitor, ...args); | ||
|  |     doError = (doError && events.error === undefined); | ||
|  |   } else if (!doError) | ||
|  |     return false; | ||
|  | 
 | ||
|  |   // If there is no 'error' event listener then throw.
 | ||
|  |   if (doError) { | ||
|  |     let er; | ||
|  |     if (args.length > 0) | ||
|  |       er = args[0]; | ||
|  |     if (er instanceof Error) { | ||
|  |       try { | ||
|  |         const capture = {}; | ||
|  |         ErrorCaptureStackTrace(capture, EventEmitter.prototype.emit); | ||
|  |       } catch (e) {} | ||
|  | 
 | ||
|  |       // Note: The comments on the `throw` lines are intentional, they show
 | ||
|  |       // up in Node's output if this results in an unhandled exception.
 | ||
|  |       throw er; // Unhandled 'error' event
 | ||
|  |     } | ||
|  | 
 | ||
|  |     let stringifiedEr; | ||
|  |     try { | ||
|  |       stringifiedEr = inspect(er); | ||
|  |     } catch (e) { | ||
|  |       stringifiedEr = er; | ||
|  |     } | ||
|  | 
 | ||
|  |     // At least give some kind of context to the user
 | ||
|  |     const err = new ERR_UNHANDLED_ERROR(stringifiedEr); | ||
|  |     err.context = er; | ||
|  |     throw err; // Unhandled 'error' event
 | ||
|  |   } | ||
|  | 
 | ||
|  |   const handler = events[type]; | ||
|  | 
 | ||
|  |   if (handler === undefined) | ||
|  |     return false; | ||
|  | 
 | ||
|  |   if (typeof handler === 'function') { | ||
|  |     const result = handler.apply(this, args); | ||
|  | 
 | ||
|  |     // We check if result is undefined first because that
 | ||
|  |     // is the most common case so we do not pay any perf
 | ||
|  |     // penalty
 | ||
|  |     if (result !== undefined && result !== null) { | ||
|  |       addCatch(this, result, type, args); | ||
|  |     } | ||
|  |   } else { | ||
|  |     const len = handler.length; | ||
|  |     const listeners = arrayClone(handler); | ||
|  |     for (let i = 0; i < len; ++i) { | ||
|  |       const result = listeners[i].apply(this, args); | ||
|  | 
 | ||
|  |       // We check if result is undefined first because that
 | ||
|  |       // is the most common case so we do not pay any perf
 | ||
|  |       // penalty.
 | ||
|  |       // This code is duplicated because extracting it away
 | ||
|  |       // would make it non-inlineable.
 | ||
|  |       if (result !== undefined && result !== null) { | ||
|  |         addCatch(this, result, type, args); | ||
|  |       } | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   return true; | ||
|  | }; | ||
|  | 
 | ||
|  | function _addListener(target, type, listener, prepend) { | ||
|  |   let m; | ||
|  |   let events; | ||
|  |   let existing; | ||
|  | 
 | ||
|  |   checkListener(listener); | ||
|  | 
 | ||
|  |   events = target._events; | ||
|  |   if (events === undefined) { | ||
|  |     events = target._events = ObjectCreate(null); | ||
|  |     target._eventsCount = 0; | ||
|  |   } else { | ||
|  |     // To avoid recursion in the case that type === "newListener"! Before
 | ||
|  |     // adding it to the listeners, first emit "newListener".
 | ||
|  |     if (events.newListener !== undefined) { | ||
|  |       target.emit('newListener', type, | ||
|  |                   nc(listener.listener, listener)); | ||
|  | 
 | ||
|  |       // Re-assign `events` because a newListener handler could have caused the
 | ||
|  |       // this._events to be assigned to a new object
 | ||
|  |       events = target._events; | ||
|  |     } | ||
|  |     existing = events[type]; | ||
|  |   } | ||
|  | 
 | ||
|  |   if (existing === undefined) { | ||
|  |     // Optimize the case of one listener. Don't need the extra array object.
 | ||
|  |     events[type] = listener; | ||
|  |     ++target._eventsCount; | ||
|  |   } else { | ||
|  |     if (typeof existing === 'function') { | ||
|  |       // Adding the second element, need to change to array.
 | ||
|  |       existing = events[type] = | ||
|  |         prepend ? [listener, existing] : [existing, listener]; | ||
|  |       // If we've already got an array, just append.
 | ||
|  |     } else if (prepend) { | ||
|  |       existing.unshift(listener); | ||
|  |     } else { | ||
|  |       existing.push(listener); | ||
|  |     } | ||
|  | 
 | ||
|  |     // Check for listener leak
 | ||
|  |     m = _getMaxListeners(target); | ||
|  |     if (m > 0 && existing.length > m && !existing.warned) { | ||
|  |       existing.warned = true; | ||
|  |       // No error code for this since it is a Warning
 | ||
|  |       // eslint-disable-next-line no-restricted-syntax
 | ||
|  |       const w = new Error('Possible EventEmitter memory leak detected. ' + | ||
|  |                           `${existing.length} ${String(type)} listeners ` + | ||
|  |                           `added to ${inspect(target, { depth: -1 })}. Use ` + | ||
|  |                           'emitter.setMaxListeners() to increase limit'); | ||
|  |       w.name = 'MaxListenersExceededWarning'; | ||
|  |       w.emitter = target; | ||
|  |       w.type = type; | ||
|  |       w.count = existing.length; | ||
|  |       process.emitWarning(w); | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   return target; | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Adds a listener to the event emitter. | ||
|  |  * @param {string | symbol} type | ||
|  |  * @param {Function} listener | ||
|  |  * @returns {EventEmitter} | ||
|  |  */ | ||
|  | EventEmitter.prototype.addListener = function addListener(type, listener) { | ||
|  |   return _addListener(this, type, listener, false); | ||
|  | }; | ||
|  | 
 | ||
|  | EventEmitter.prototype.on = EventEmitter.prototype.addListener; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Adds the `listener` function to the beginning of | ||
|  |  * the listeners array. | ||
|  |  * @param {string | symbol} type | ||
|  |  * @param {Function} listener | ||
|  |  * @returns {EventEmitter} | ||
|  |  */ | ||
|  | EventEmitter.prototype.prependListener = | ||
|  |     function prependListener(type, listener) { | ||
|  |       return _addListener(this, type, listener, true); | ||
|  |     }; | ||
|  | 
 | ||
|  | function onceWrapper() { | ||
|  |   if (!this.fired) { | ||
|  |     this.target.removeListener(this.type, this.wrapFn); | ||
|  |     this.fired = true; | ||
|  |     if (arguments.length === 0) | ||
|  |       return this.listener.call(this.target); | ||
|  |     return this.listener.apply(this.target, arguments); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | function _onceWrap(target, type, listener) { | ||
|  |   const state = { fired: false, wrapFn: undefined, target, type, listener }; | ||
|  |   const wrapped = onceWrapper.bind(state); | ||
|  |   wrapped.listener = listener; | ||
|  |   state.wrapFn = wrapped; | ||
|  |   return wrapped; | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Adds a one-time `listener` function to the event emitter. | ||
|  |  * @param {string | symbol} type | ||
|  |  * @param {Function} listener | ||
|  |  * @returns {EventEmitter} | ||
|  |  */ | ||
|  | EventEmitter.prototype.once = function once(type, listener) { | ||
|  |   checkListener(listener); | ||
|  | 
 | ||
|  |   this.on(type, _onceWrap(this, type, listener)); | ||
|  |   return this; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Adds a one-time `listener` function to the beginning of | ||
|  |  * the listeners array. | ||
|  |  * @param {string | symbol} type | ||
|  |  * @param {Function} listener | ||
|  |  * @returns {EventEmitter} | ||
|  |  */ | ||
|  | EventEmitter.prototype.prependOnceListener = | ||
|  |     function prependOnceListener(type, listener) { | ||
|  |       checkListener(listener); | ||
|  | 
 | ||
|  |       this.prependListener(type, _onceWrap(this, type, listener)); | ||
|  |       return this; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  | /** | ||
|  |  * Removes the specified `listener` from the listeners array. | ||
|  |  * @param {string | symbol} type | ||
|  |  * @param {Function} listener | ||
|  |  * @returns {EventEmitter} | ||
|  |  */ | ||
|  | EventEmitter.prototype.removeListener = | ||
|  |     function removeListener(type, listener) { | ||
|  |       checkListener(listener); | ||
|  | 
 | ||
|  |       const events = this._events; | ||
|  |       if (events === undefined) | ||
|  |         return this; | ||
|  | 
 | ||
|  |       const list = events[type]; | ||
|  |       if (list === undefined) | ||
|  |         return this; | ||
|  | 
 | ||
|  |       if (list === listener || list.listener === listener) { | ||
|  |         if (--this._eventsCount === 0) | ||
|  |           this._events = ObjectCreate(null); | ||
|  |         else { | ||
|  |           delete events[type]; | ||
|  |           if (events.removeListener) | ||
|  |             this.emit('removeListener', type, list.listener || listener); | ||
|  |         } | ||
|  |       } else if (typeof list !== 'function') { | ||
|  |         let position = -1; | ||
|  | 
 | ||
|  |         for (let i = list.length - 1; i >= 0; i--) { | ||
|  |           if (list[i] === listener || list[i].listener === listener) { | ||
|  |             position = i; | ||
|  |             break; | ||
|  |           } | ||
|  |         } | ||
|  | 
 | ||
|  |         if (position < 0) | ||
|  |           return this; | ||
|  | 
 | ||
|  |         if (position === 0) | ||
|  |           list.shift(); | ||
|  |         else { | ||
|  |           spliceOne(list, position); | ||
|  |         } | ||
|  | 
 | ||
|  |         if (list.length === 1) | ||
|  |           events[type] = list[0]; | ||
|  | 
 | ||
|  |         if (events.removeListener !== undefined) | ||
|  |           this.emit('removeListener', type, listener); | ||
|  |       } | ||
|  | 
 | ||
|  |       return this; | ||
|  |     }; | ||
|  | 
 | ||
|  | EventEmitter.prototype.off = EventEmitter.prototype.removeListener; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Removes all listeners from the event emitter. (Only | ||
|  |  * removes listeners for a specific event name if specified | ||
|  |  * as `type`). | ||
|  |  * @param {string | symbol} [type] | ||
|  |  * @returns {EventEmitter} | ||
|  |  */ | ||
|  | EventEmitter.prototype.removeAllListeners = | ||
|  |     function removeAllListeners(type) { | ||
|  |       const events = this._events; | ||
|  |       if (events === undefined) | ||
|  |         return this; | ||
|  | 
 | ||
|  |       // Not listening for removeListener, no need to emit
 | ||
|  |       if (events.removeListener === undefined) { | ||
|  |         if (arguments.length === 0) { | ||
|  |           this._events = ObjectCreate(null); | ||
|  |           this._eventsCount = 0; | ||
|  |         } else if (events[type] !== undefined) { | ||
|  |           if (--this._eventsCount === 0) | ||
|  |             this._events = ObjectCreate(null); | ||
|  |           else | ||
|  |             delete events[type]; | ||
|  |         } | ||
|  |         return this; | ||
|  |       } | ||
|  | 
 | ||
|  |       // Emit removeListener for all listeners on all events
 | ||
|  |       if (arguments.length === 0) { | ||
|  |         for (const key of ReflectOwnKeys(events)) { | ||
|  |           if (key === 'removeListener') continue; | ||
|  |           this.removeAllListeners(key); | ||
|  |         } | ||
|  |         this.removeAllListeners('removeListener'); | ||
|  |         this._events = ObjectCreate(null); | ||
|  |         this._eventsCount = 0; | ||
|  |         return this; | ||
|  |       } | ||
|  | 
 | ||
|  |       const listeners = events[type]; | ||
|  | 
 | ||
|  |       if (typeof listeners === 'function') { | ||
|  |         this.removeListener(type, listeners); | ||
|  |       } else if (listeners !== undefined) { | ||
|  |         // LIFO order
 | ||
|  |         for (let i = listeners.length - 1; i >= 0; i--) { | ||
|  |           this.removeListener(type, listeners[i]); | ||
|  |         } | ||
|  |       } | ||
|  | 
 | ||
|  |       return this; | ||
|  |     }; | ||
|  | 
 | ||
|  | function _listeners(target, type, unwrap) { | ||
|  |   const events = target._events; | ||
|  | 
 | ||
|  |   if (events === undefined) | ||
|  |     return []; | ||
|  | 
 | ||
|  |   const evlistener = events[type]; | ||
|  |   if (evlistener === undefined) | ||
|  |     return []; | ||
|  | 
 | ||
|  |   if (typeof evlistener === 'function') | ||
|  |     return unwrap ? [evlistener.listener || evlistener] : [evlistener]; | ||
|  | 
 | ||
|  |   return unwrap ? | ||
|  |     unwrapListeners(evlistener) : arrayClone(evlistener); | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns a copy of the array of listeners for the event name | ||
|  |  * specified as `type`. | ||
|  |  * @param {string | symbol} type | ||
|  |  * @returns {Function[]} | ||
|  |  */ | ||
|  | EventEmitter.prototype.listeners = function listeners(type) { | ||
|  |   return _listeners(this, type, true); | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns a copy of the array of listeners and wrappers for | ||
|  |  * the event name specified as `type`. | ||
|  |  * @param {string | symbol} type | ||
|  |  * @returns {Function[]} | ||
|  |  */ | ||
|  | EventEmitter.prototype.rawListeners = function rawListeners(type) { | ||
|  |   return _listeners(this, type, false); | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the number of listeners listening to the event name | ||
|  |  * specified as `type`. | ||
|  |  * @deprecated since v3.2.0 | ||
|  |  * @param {EventEmitter} emitter | ||
|  |  * @param {string | symbol} type | ||
|  |  * @returns {number} | ||
|  |  */ | ||
|  | EventEmitter.listenerCount = function(emitter, type) { | ||
|  |   if (typeof emitter.listenerCount === 'function') { | ||
|  |     return emitter.listenerCount(type); | ||
|  |   } | ||
|  |   return emitter.listenerCount(type); | ||
|  | }; | ||
|  | 
 | ||
|  | EventEmitter.prototype.listenerCount = listenerCount; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the number of listeners listening to event name | ||
|  |  * specified as `type`. | ||
|  |  * @param {string | symbol} type | ||
|  |  * @returns {number} | ||
|  |  */ | ||
|  | function listenerCount(type) { | ||
|  |   const events = this._events; | ||
|  | 
 | ||
|  |   if (events !== undefined) { | ||
|  |     const evlistener = events[type]; | ||
|  | 
 | ||
|  |     if (typeof evlistener === 'function') { | ||
|  |       return 1; | ||
|  |     } else if (evlistener !== undefined) { | ||
|  |       return evlistener.length; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   return 0; | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns an array listing the events for which | ||
|  |  * the emitter has registered listeners. | ||
|  |  * @returns {any[]} | ||
|  |  */ | ||
|  | EventEmitter.prototype.eventNames = function eventNames() { | ||
|  |   return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; | ||
|  | }; | ||
|  | 
 | ||
|  | function arrayClone(arr) { | ||
|  |   // At least since V8 8.3, this implementation is faster than the previous
 | ||
|  |   // which always used a simple for-loop
 | ||
|  |   switch (arr.length) { | ||
|  |     case 2: return [arr[0], arr[1]]; | ||
|  |     case 3: return [arr[0], arr[1], arr[2]]; | ||
|  |     case 4: return [arr[0], arr[1], arr[2], arr[3]]; | ||
|  |     case 5: return [arr[0], arr[1], arr[2], arr[3], arr[4]]; | ||
|  |     case 6: return [arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]]; | ||
|  |   } | ||
|  |   return ArrayPrototypeSlice(arr); | ||
|  | } | ||
|  | 
 | ||
|  | function unwrapListeners(arr) { | ||
|  |   const ret = arrayClone(arr); | ||
|  |   for (let i = 0; i < ret.length; ++i) { | ||
|  |     const orig = ret[i].listener; | ||
|  |     if (typeof orig === 'function') | ||
|  |       ret[i] = orig; | ||
|  |   } | ||
|  |   return ret; | ||
|  | } |