xref: /third_party/node/lib/internal/util.js (revision 1cb0ef41)
1'use strict';
2
3const {
4  ArrayBufferPrototypeGetByteLength,
5  ArrayFrom,
6  ArrayIsArray,
7  ArrayPrototypePush,
8  ArrayPrototypeSlice,
9  ArrayPrototypeSort,
10  Error,
11  FunctionPrototypeCall,
12  ObjectCreate,
13  ObjectDefineProperties,
14  ObjectDefineProperty,
15  ObjectGetOwnPropertyDescriptor,
16  ObjectGetOwnPropertyDescriptors,
17  ObjectGetPrototypeOf,
18  ObjectFreeze,
19  ObjectPrototypeHasOwnProperty,
20  ObjectSetPrototypeOf,
21  ObjectValues,
22  Promise,
23  ReflectApply,
24  ReflectConstruct,
25  RegExpPrototypeExec,
26  RegExpPrototypeGetDotAll,
27  RegExpPrototypeGetGlobal,
28  RegExpPrototypeGetHasIndices,
29  RegExpPrototypeGetIgnoreCase,
30  RegExpPrototypeGetMultiline,
31  RegExpPrototypeGetSticky,
32  RegExpPrototypeGetUnicode,
33  RegExpPrototypeGetSource,
34  SafeMap,
35  SafeSet,
36  SafeWeakMap,
37  StringPrototypeReplace,
38  StringPrototypeToLowerCase,
39  StringPrototypeToUpperCase,
40  Symbol,
41  SymbolFor,
42  SymbolReplace,
43  SymbolSplit,
44} = primordials;
45
46const {
47  hideStackFrames,
48  codes: {
49    ERR_NO_CRYPTO,
50    ERR_UNKNOWN_SIGNAL,
51  },
52  uvErrmapGet,
53  overrideStackTrace,
54} = require('internal/errors');
55const { signals } = internalBinding('constants').os;
56const {
57  isArrayBufferDetached: _isArrayBufferDetached,
58  privateSymbols: {
59    arrow_message_private_symbol,
60    decorated_private_symbol,
61  },
62  sleep: _sleep,
63  toUSVString: _toUSVString,
64} = internalBinding('util');
65const { isNativeError } = internalBinding('types');
66const { getOptionValue } = require('internal/options');
67
68const noCrypto = !process.versions.openssl;
69
70const experimentalWarnings = new SafeSet();
71
72const colorRegExp = /\u001b\[\d\d?m/g; // eslint-disable-line no-control-regex
73
74const unpairedSurrogateRe =
75  /(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])/;
76function toUSVString(val) {
77  const str = `${val}`;
78  // As of V8 5.5, `str.search()` (and `unpairedSurrogateRe[@@search]()`) are
79  // slower than `unpairedSurrogateRe.exec()`.
80  const match = RegExpPrototypeExec(unpairedSurrogateRe, str);
81  if (!match)
82    return str;
83  return _toUSVString(str, match.index);
84}
85
86let uvBinding;
87
88function lazyUv() {
89  uvBinding ??= internalBinding('uv');
90  return uvBinding;
91}
92
93function removeColors(str) {
94  return StringPrototypeReplace(str, colorRegExp, '');
95}
96
97function isError(e) {
98  // An error could be an instance of Error while not being a native error
99  // or could be from a different realm and not be instance of Error but still
100  // be a native error.
101  return isNativeError(e) || e instanceof Error;
102}
103
104// Keep a list of deprecation codes that have been warned on so we only warn on
105// each one once.
106const codesWarned = new SafeSet();
107
108let validateString;
109
110function getDeprecationWarningEmitter(
111  code, msg, deprecated, useEmitSync,
112  shouldEmitWarning = () => true,
113) {
114  let warned = false;
115  return function() {
116    if (!warned && shouldEmitWarning()) {
117      warned = true;
118      if (code !== undefined) {
119        if (!codesWarned.has(code)) {
120          const emitWarning = useEmitSync ?
121            require('internal/process/warning').emitWarningSync :
122            process.emitWarning;
123          emitWarning(msg, 'DeprecationWarning', code, deprecated);
124          codesWarned.add(code);
125        }
126      } else {
127        process.emitWarning(msg, 'DeprecationWarning', deprecated);
128      }
129    }
130  };
131}
132
133function isPendingDeprecation() {
134  return getOptionValue('--pending-deprecation') &&
135    !getOptionValue('--no-deprecation');
136}
137
138// Internal deprecator for pending --pending-deprecation. This can be invoked
139// at snapshot building time as the warning permission is only queried at
140// run time.
141function pendingDeprecate(fn, msg, code) {
142  const emitDeprecationWarning = getDeprecationWarningEmitter(
143    code, msg, deprecated, false, isPendingDeprecation,
144  );
145  function deprecated(...args) {
146    emitDeprecationWarning();
147    return ReflectApply(fn, this, args);
148  }
149  return deprecated;
150}
151
152// Mark that a method should not be used.
153// Returns a modified function which warns once by default.
154// If --no-deprecation is set, then it is a no-op.
155function deprecate(fn, msg, code, useEmitSync) {
156  if (process.noDeprecation === true) {
157    return fn;
158  }
159
160  // Lazy-load to avoid a circular dependency.
161  if (validateString === undefined)
162    ({ validateString } = require('internal/validators'));
163
164  if (code !== undefined)
165    validateString(code, 'code');
166
167  const emitDeprecationWarning = getDeprecationWarningEmitter(
168    code, msg, deprecated, useEmitSync,
169  );
170
171  function deprecated(...args) {
172    emitDeprecationWarning();
173    if (new.target) {
174      return ReflectConstruct(fn, args, new.target);
175    }
176    return ReflectApply(fn, this, args);
177  }
178
179  // The wrapper will keep the same prototype as fn to maintain prototype chain
180  ObjectSetPrototypeOf(deprecated, fn);
181  if (fn.prototype) {
182    // Setting this (rather than using Object.setPrototype, as above) ensures
183    // that calling the unwrapped constructor gives an instanceof the wrapped
184    // constructor.
185    deprecated.prototype = fn.prototype;
186  }
187
188  return deprecated;
189}
190
191function decorateErrorStack(err) {
192  if (!(isError(err) && err.stack) || err[decorated_private_symbol])
193    return;
194
195  const arrow = err[arrow_message_private_symbol];
196
197  if (arrow) {
198    err.stack = arrow + err.stack;
199    err[decorated_private_symbol] = true;
200  }
201}
202
203function assertCrypto() {
204  if (noCrypto)
205    throw new ERR_NO_CRYPTO();
206}
207
208// Return undefined if there is no match.
209// Move the "slow cases" to a separate function to make sure this function gets
210// inlined properly. That prioritizes the common case.
211function normalizeEncoding(enc) {
212  if (enc == null || enc === 'utf8' || enc === 'utf-8') return 'utf8';
213  return slowCases(enc);
214}
215
216function slowCases(enc) {
217  switch (enc.length) {
218    case 4:
219      if (enc === 'UTF8') return 'utf8';
220      if (enc === 'ucs2' || enc === 'UCS2') return 'utf16le';
221      enc = `${enc}`.toLowerCase();
222      if (enc === 'utf8') return 'utf8';
223      if (enc === 'ucs2') return 'utf16le';
224      break;
225    case 3:
226      if (enc === 'hex' || enc === 'HEX' ||
227          `${enc}`.toLowerCase() === 'hex')
228        return 'hex';
229      break;
230    case 5:
231      if (enc === 'ascii') return 'ascii';
232      if (enc === 'ucs-2') return 'utf16le';
233      if (enc === 'UTF-8') return 'utf8';
234      if (enc === 'ASCII') return 'ascii';
235      if (enc === 'UCS-2') return 'utf16le';
236      enc = `${enc}`.toLowerCase();
237      if (enc === 'utf-8') return 'utf8';
238      if (enc === 'ascii') return 'ascii';
239      if (enc === 'ucs-2') return 'utf16le';
240      break;
241    case 6:
242      if (enc === 'base64') return 'base64';
243      if (enc === 'latin1' || enc === 'binary') return 'latin1';
244      if (enc === 'BASE64') return 'base64';
245      if (enc === 'LATIN1' || enc === 'BINARY') return 'latin1';
246      enc = `${enc}`.toLowerCase();
247      if (enc === 'base64') return 'base64';
248      if (enc === 'latin1' || enc === 'binary') return 'latin1';
249      break;
250    case 7:
251      if (enc === 'utf16le' || enc === 'UTF16LE' ||
252          `${enc}`.toLowerCase() === 'utf16le')
253        return 'utf16le';
254      break;
255    case 8:
256      if (enc === 'utf-16le' || enc === 'UTF-16LE' ||
257        `${enc}`.toLowerCase() === 'utf-16le')
258        return 'utf16le';
259      break;
260    case 9:
261      if (enc === 'base64url' || enc === 'BASE64URL' ||
262          `${enc}`.toLowerCase() === 'base64url')
263        return 'base64url';
264      break;
265    default:
266      if (enc === '') return 'utf8';
267  }
268}
269
270function emitExperimentalWarning(feature) {
271  if (experimentalWarnings.has(feature)) return;
272  const msg = `${feature} is an experimental feature and might change at any time`;
273  experimentalWarnings.add(feature);
274  process.emitWarning(msg, 'ExperimentalWarning');
275}
276
277function filterDuplicateStrings(items, low) {
278  const map = new SafeMap();
279  for (let i = 0; i < items.length; i++) {
280    const item = items[i];
281    const key = StringPrototypeToLowerCase(item);
282    if (low) {
283      map.set(key, key);
284    } else {
285      map.set(key, item);
286    }
287  }
288  return ArrayPrototypeSort(ArrayFrom(map.values()));
289}
290
291function cachedResult(fn) {
292  let result;
293  return () => {
294    if (result === undefined)
295      result = fn();
296    return ArrayPrototypeSlice(result);
297  };
298}
299
300// Useful for Wrapping an ES6 Class with a constructor Function that
301// does not require the new keyword. For instance:
302//   class A { constructor(x) {this.x = x;}}
303//   const B = createClassWrapper(A);
304//   B() instanceof A // true
305//   B() instanceof B // true
306function createClassWrapper(type) {
307  function fn(...args) {
308    return ReflectConstruct(type, args, new.target || type);
309  }
310  // Mask the wrapper function name and length values
311  ObjectDefineProperties(fn, {
312    name: { __proto__: null, value: type.name },
313    length: { __proto__: null, value: type.length },
314  });
315  ObjectSetPrototypeOf(fn, type);
316  fn.prototype = type.prototype;
317  return fn;
318}
319
320let signalsToNamesMapping;
321function getSignalsToNamesMapping() {
322  if (signalsToNamesMapping !== undefined)
323    return signalsToNamesMapping;
324
325  signalsToNamesMapping = ObjectCreate(null);
326  for (const key in signals) {
327    signalsToNamesMapping[signals[key]] = key;
328  }
329
330  return signalsToNamesMapping;
331}
332
333function convertToValidSignal(signal) {
334  if (typeof signal === 'number' && getSignalsToNamesMapping()[signal])
335    return signal;
336
337  if (typeof signal === 'string') {
338    const signalName = signals[StringPrototypeToUpperCase(signal)];
339    if (signalName) return signalName;
340  }
341
342  throw new ERR_UNKNOWN_SIGNAL(signal);
343}
344
345function getConstructorOf(obj) {
346  while (obj) {
347    const descriptor = ObjectGetOwnPropertyDescriptor(obj, 'constructor');
348    if (descriptor !== undefined &&
349        typeof descriptor.value === 'function' &&
350        descriptor.value.name !== '') {
351      return descriptor.value;
352    }
353
354    obj = ObjectGetPrototypeOf(obj);
355  }
356
357  return null;
358}
359
360let cachedURL;
361let cachedCWD;
362
363/**
364 * Get the current working directory while accounting for the possibility that it has been deleted.
365 * `process.cwd()` can fail if the parent directory is deleted while the process runs.
366 * @returns {URL} The current working directory or the volume root if it cannot be determined.
367 */
368function getCWDURL() {
369  const { sep } = require('path');
370  const { pathToFileURL } = require('internal/url');
371
372  let cwd;
373
374  try {
375    // The implementation of `process.cwd()` already uses proper cache when it can.
376    // It's a relatively cheap call performance-wise for the most common use case.
377    cwd = process.cwd();
378  } catch {
379    cachedURL ??= pathToFileURL(sep);
380  }
381
382  if (cwd != null && cwd !== cachedCWD) {
383    cachedURL = pathToFileURL(cwd + sep);
384    cachedCWD = cwd;
385  }
386
387  return cachedURL;
388}
389
390function getSystemErrorName(err) {
391  const entry = uvErrmapGet(err);
392  return entry ? entry[0] : `Unknown system error ${err}`;
393}
394
395function getSystemErrorMap() {
396  return lazyUv().getErrorMap();
397}
398
399const kCustomPromisifiedSymbol = SymbolFor('nodejs.util.promisify.custom');
400const kCustomPromisifyArgsSymbol = Symbol('customPromisifyArgs');
401
402let validateFunction;
403
404function promisify(original) {
405  // Lazy-load to avoid a circular dependency.
406  if (validateFunction === undefined)
407    ({ validateFunction } = require('internal/validators'));
408
409  validateFunction(original, 'original');
410
411  if (original[kCustomPromisifiedSymbol]) {
412    const fn = original[kCustomPromisifiedSymbol];
413
414    validateFunction(fn, 'util.promisify.custom');
415
416    return ObjectDefineProperty(fn, kCustomPromisifiedSymbol, {
417      __proto__: null,
418      value: fn, enumerable: false, writable: false, configurable: true,
419    });
420  }
421
422  // Names to create an object from in case the callback receives multiple
423  // arguments, e.g. ['bytesRead', 'buffer'] for fs.read.
424  const argumentNames = original[kCustomPromisifyArgsSymbol];
425
426  function fn(...args) {
427    return new Promise((resolve, reject) => {
428      ArrayPrototypePush(args, (err, ...values) => {
429        if (err) {
430          return reject(err);
431        }
432        if (argumentNames !== undefined && values.length > 1) {
433          const obj = {};
434          for (let i = 0; i < argumentNames.length; i++)
435            obj[argumentNames[i]] = values[i];
436          resolve(obj);
437        } else {
438          resolve(values[0]);
439        }
440      });
441      ReflectApply(original, this, args);
442    });
443  }
444
445  ObjectSetPrototypeOf(fn, ObjectGetPrototypeOf(original));
446
447  ObjectDefineProperty(fn, kCustomPromisifiedSymbol, {
448    __proto__: null,
449    value: fn, enumerable: false, writable: false, configurable: true,
450  });
451
452  const descriptors = ObjectGetOwnPropertyDescriptors(original);
453  const propertiesValues = ObjectValues(descriptors);
454  for (let i = 0; i < propertiesValues.length; i++) {
455    // We want to use null-prototype objects to not rely on globally mutable
456    // %Object.prototype%.
457    ObjectSetPrototypeOf(propertiesValues[i], null);
458  }
459  return ObjectDefineProperties(fn, descriptors);
460}
461
462promisify.custom = kCustomPromisifiedSymbol;
463
464// The built-in Array#join is slower in v8 6.0
465function join(output, separator) {
466  let str = '';
467  if (output.length !== 0) {
468    const lastIndex = output.length - 1;
469    for (let i = 0; i < lastIndex; i++) {
470      // It is faster not to use a template string here
471      str += output[i];
472      str += separator;
473    }
474    str += output[lastIndex];
475  }
476  return str;
477}
478
479// As of V8 6.6, depending on the size of the array, this is anywhere
480// between 1.5-10x faster than the two-arg version of Array#splice()
481function spliceOne(list, index) {
482  for (; index + 1 < list.length; index++)
483    list[index] = list[index + 1];
484  list.pop();
485}
486
487const kNodeModulesRE = /^(.*)[\\/]node_modules[\\/]/;
488
489let getStructuredStack;
490
491function isInsideNodeModules() {
492  if (getStructuredStack === undefined) {
493    // Lazy-load to avoid a circular dependency.
494    const { runInNewContext } = require('vm');
495    // Use `runInNewContext()` to get something tamper-proof and
496    // side-effect-free. Since this is currently only used for a deprecated API,
497    // the perf implications should be okay.
498    getStructuredStack = runInNewContext(`(function() {
499      try { Error.stackTraceLimit = Infinity; } catch {}
500      return function structuredStack() {
501        const e = new Error();
502        overrideStackTrace.set(e, (err, trace) => trace);
503        return e.stack;
504      };
505    })()`, { overrideStackTrace }, { filename: 'structured-stack' });
506  }
507
508  const stack = getStructuredStack();
509
510  // Iterate over all stack frames and look for the first one not coming
511  // from inside Node.js itself:
512  if (ArrayIsArray(stack)) {
513    for (const frame of stack) {
514      const filename = frame.getFileName();
515      // If a filename does not start with / or contain \,
516      // it's likely from Node.js core.
517      if (RegExpPrototypeExec(/^\/|\\/, filename) === null)
518        continue;
519      return RegExpPrototypeExec(kNodeModulesRE, filename) !== null;
520    }
521  }
522  return false;
523}
524
525function once(callback) {
526  let called = false;
527  return function(...args) {
528    if (called) return;
529    called = true;
530    return ReflectApply(callback, this, args);
531  };
532}
533
534let validateUint32;
535
536function sleep(msec) {
537  // Lazy-load to avoid a circular dependency.
538  if (validateUint32 === undefined)
539    ({ validateUint32 } = require('internal/validators'));
540
541  validateUint32(msec, 'msec');
542  _sleep(msec);
543}
544
545function createDeferredPromise() {
546  let resolve;
547  let reject;
548  const promise = new Promise((res, rej) => {
549    resolve = res;
550    reject = rej;
551  });
552
553  return { promise, resolve, reject };
554}
555
556// https://heycam.github.io/webidl/#define-the-operations
557function defineOperation(target, name, method) {
558  ObjectDefineProperty(target, name, {
559    __proto__: null,
560    writable: true,
561    enumerable: true,
562    configurable: true,
563    value: method,
564  });
565}
566
567// https://heycam.github.io/webidl/#es-interfaces
568function exposeInterface(target, name, interfaceObject) {
569  ObjectDefineProperty(target, name, {
570    __proto__: null,
571    writable: true,
572    enumerable: false,
573    configurable: true,
574    value: interfaceObject,
575  });
576}
577
578function defineLazyProperties(target, id, keys, enumerable = true) {
579  const descriptors = { __proto__: null };
580  let mod;
581  for (let i = 0; i < keys.length; i++) {
582    const key = keys[i];
583    let lazyLoadedValue;
584    function set(value) {
585      ObjectDefineProperty(target, key, {
586        __proto__: null,
587        writable: true,
588        value,
589      });
590    }
591    ObjectDefineProperty(set, 'name', {
592      __proto__: null,
593      value: `set ${key}`,
594    });
595    function get() {
596      mod ??= require(id);
597      if (lazyLoadedValue === undefined) {
598        lazyLoadedValue = mod[key];
599        set(lazyLoadedValue);
600      }
601      return lazyLoadedValue;
602    }
603    ObjectDefineProperty(get, 'name', {
604      __proto__: null,
605      value: `get ${key}`,
606    });
607    descriptors[key] = {
608      __proto__: null,
609      configurable: true,
610      enumerable,
611      get,
612      set,
613    };
614  }
615  ObjectDefineProperties(target, descriptors);
616}
617
618function defineReplaceableLazyAttribute(target, id, keys, writable = true) {
619  let mod;
620  for (let i = 0; i < keys.length; i++) {
621    const key = keys[i];
622    let value;
623    let setterCalled = false;
624
625    function get() {
626      if (setterCalled) {
627        return value;
628      }
629      mod ??= require(id);
630      value ??= mod[key];
631      return value;
632    }
633
634    ObjectDefineProperty(get, 'name', {
635      __proto__: null,
636      value: `get ${key}`,
637    });
638
639    function set(val) {
640      setterCalled = true;
641      value = val;
642    }
643    ObjectDefineProperty(set, 'name', {
644      __proto__: null,
645      value: `set ${key}`,
646    });
647
648    ObjectDefineProperty(target, key, {
649      __proto__: null,
650      enumerable: true,
651      configurable: true,
652      get,
653      set: writable ? set : undefined,
654    });
655  }
656}
657
658function exposeLazyInterfaces(target, id, keys) {
659  defineLazyProperties(target, id, keys, false);
660}
661
662let _DOMException;
663const lazyDOMExceptionClass = () => {
664  _DOMException ??= internalBinding('messaging').DOMException;
665  return _DOMException;
666};
667
668const lazyDOMException = hideStackFrames((message, name) => {
669  _DOMException ??= internalBinding('messaging').DOMException;
670  return new _DOMException(message, name);
671});
672
673const kEnumerableProperty = ObjectCreate(null);
674kEnumerableProperty.enumerable = true;
675ObjectFreeze(kEnumerableProperty);
676
677const kEmptyObject = ObjectFreeze(ObjectCreate(null));
678
679function filterOwnProperties(source, keys) {
680  const filtered = ObjectCreate(null);
681  for (let i = 0; i < keys.length; i++) {
682    const key = keys[i];
683    if (ObjectPrototypeHasOwnProperty(source, key)) {
684      filtered[key] = source[key];
685    }
686  }
687
688  return filtered;
689}
690
691/**
692 * Mimics `obj[key] = value` but ignoring potential prototype inheritance.
693 * @param {any} obj
694 * @param {string} key
695 * @param {any} value
696 * @returns {any}
697 */
698function setOwnProperty(obj, key, value) {
699  return ObjectDefineProperty(obj, key, {
700    __proto__: null,
701    configurable: true,
702    enumerable: true,
703    value,
704    writable: true,
705  });
706}
707
708let internalGlobal;
709function getInternalGlobal() {
710  if (internalGlobal == null) {
711    // Lazy-load to avoid a circular dependency.
712    const { runInNewContext } = require('vm');
713    internalGlobal = runInNewContext('this', undefined, { contextName: 'internal' });
714  }
715  return internalGlobal;
716}
717
718function SideEffectFreeRegExpPrototypeExec(regex, string) {
719  const { RegExp: RegExpFromAnotherRealm } = getInternalGlobal();
720  return FunctionPrototypeCall(RegExpFromAnotherRealm.prototype.exec, regex, string);
721}
722
723const crossRelmRegexes = new SafeWeakMap();
724function getCrossRelmRegex(regex) {
725  const cached = crossRelmRegexes.get(regex);
726  if (cached) return cached;
727
728  let flagString = '';
729  if (RegExpPrototypeGetHasIndices(regex)) flagString += 'd';
730  if (RegExpPrototypeGetGlobal(regex)) flagString += 'g';
731  if (RegExpPrototypeGetIgnoreCase(regex)) flagString += 'i';
732  if (RegExpPrototypeGetMultiline(regex)) flagString += 'm';
733  if (RegExpPrototypeGetDotAll(regex)) flagString += 's';
734  if (RegExpPrototypeGetUnicode(regex)) flagString += 'u';
735  if (RegExpPrototypeGetSticky(regex)) flagString += 'y';
736
737  const { RegExp: RegExpFromAnotherRealm } = getInternalGlobal();
738  const crossRelmRegex = new RegExpFromAnotherRealm(RegExpPrototypeGetSource(regex), flagString);
739  crossRelmRegexes.set(regex, crossRelmRegex);
740  return crossRelmRegex;
741}
742
743function SideEffectFreeRegExpPrototypeSymbolReplace(regex, string, replacement) {
744  return getCrossRelmRegex(regex)[SymbolReplace](string, replacement);
745}
746
747function SideEffectFreeRegExpPrototypeSymbolSplit(regex, string, limit = undefined) {
748  return getCrossRelmRegex(regex)[SymbolSplit](string, limit);
749}
750
751
752function isArrayBufferDetached(value) {
753  if (ArrayBufferPrototypeGetByteLength(value) === 0) {
754    return _isArrayBufferDetached(value);
755  }
756
757  return false;
758}
759
760/**
761 * Helper function to lazy-load an initialize-once value.
762 * @template T Return value of initializer
763 * @param {()=>T} initializer Initializer of the lazily loaded value.
764 * @returns {()=>T}
765 */
766function getLazy(initializer) {
767  let value;
768  let initialized = false;
769  return function() {
770    if (initialized === false) {
771      value = initializer();
772      initialized = true;
773    }
774    return value;
775  };
776}
777
778// Setup user-facing NODE_V8_COVERAGE environment variable that writes
779// ScriptCoverage objects to a specified directory.
780function setupCoverageHooks(dir) {
781  const cwd = require('internal/process/execution').tryGetCwd();
782  const { resolve } = require('path');
783  const coverageDirectory = resolve(cwd, dir);
784  const { sourceMapCacheToObject } =
785    require('internal/source_map/source_map_cache');
786
787  if (process.features.inspector) {
788    internalBinding('profiler').setCoverageDirectory(coverageDirectory);
789    internalBinding('profiler').setSourceMapCacheGetter(sourceMapCacheToObject);
790  } else {
791    process.emitWarning('The inspector is disabled, ' +
792                        'coverage could not be collected',
793                        'Warning');
794    return '';
795  }
796  return coverageDirectory;
797}
798
799module.exports = {
800  getLazy,
801  assertCrypto,
802  cachedResult,
803  convertToValidSignal,
804  createClassWrapper,
805  createDeferredPromise,
806  decorateErrorStack,
807  defineOperation,
808  defineLazyProperties,
809  defineReplaceableLazyAttribute,
810  deprecate,
811  emitExperimentalWarning,
812  exposeInterface,
813  exposeLazyInterfaces,
814  filterDuplicateStrings,
815  filterOwnProperties,
816  getConstructorOf,
817  getCWDURL,
818  getInternalGlobal,
819  getSystemErrorMap,
820  getSystemErrorName,
821  isArrayBufferDetached,
822  isError,
823  isInsideNodeModules,
824  join,
825  lazyDOMException,
826  lazyDOMExceptionClass,
827  normalizeEncoding,
828  once,
829  promisify,
830  SideEffectFreeRegExpPrototypeExec,
831  SideEffectFreeRegExpPrototypeSymbolReplace,
832  SideEffectFreeRegExpPrototypeSymbolSplit,
833  sleep,
834  spliceOne,
835  setupCoverageHooks,
836  toUSVString,
837  removeColors,
838
839  // Symbol used to customize promisify conversion
840  customPromisifyArgs: kCustomPromisifyArgsSymbol,
841
842  // Symbol used to provide a custom inspect function for an object as an
843  // alternative to using 'inspect'
844  customInspectSymbol: SymbolFor('nodejs.util.inspect.custom'),
845
846  // Used by the buffer module to capture an internal reference to the
847  // default isEncoding implementation, just in case userland overrides it.
848  kIsEncodingSymbol: Symbol('kIsEncodingSymbol'),
849  kVmBreakFirstLineSymbol: Symbol('kVmBreakFirstLineSymbol'),
850
851  kEmptyObject,
852  kEnumerableProperty,
853  setOwnProperty,
854  pendingDeprecate,
855};
856