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
						
					
					
				| // 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;
 | |
| }
 |