• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const {
4  ArrayPrototypeForEach,
5} = primordials;
6
7const {
8  compileFunction,
9  isContext: _isContext,
10} = internalBinding('contextify');
11const {
12  validateArray,
13  validateBoolean,
14  validateBuffer,
15  validateFunction,
16  validateObject,
17  validateString,
18  validateStringArray,
19  validateUint32,
20} = require('internal/validators');
21const {
22  ERR_INVALID_ARG_TYPE,
23} = require('internal/errors').codes;
24
25function isContext(object) {
26  validateObject(object, 'object', { __proto__: null, allowArray: true });
27
28  return _isContext(object);
29}
30
31function internalCompileFunction(code, params, options) {
32  validateString(code, 'code');
33  if (params !== undefined) {
34    validateStringArray(params, 'params');
35  }
36
37  const {
38    filename = '',
39    columnOffset = 0,
40    lineOffset = 0,
41    cachedData = undefined,
42    produceCachedData = false,
43    parsingContext = undefined,
44    contextExtensions = [],
45    importModuleDynamically,
46  } = options;
47
48  validateString(filename, 'options.filename');
49  validateUint32(columnOffset, 'options.columnOffset');
50  validateUint32(lineOffset, 'options.lineOffset');
51  if (cachedData !== undefined)
52    validateBuffer(cachedData, 'options.cachedData');
53  validateBoolean(produceCachedData, 'options.produceCachedData');
54  if (parsingContext !== undefined) {
55    if (
56      typeof parsingContext !== 'object' ||
57      parsingContext === null ||
58      !isContext(parsingContext)
59    ) {
60      throw new ERR_INVALID_ARG_TYPE(
61        'options.parsingContext',
62        'Context',
63        parsingContext,
64      );
65    }
66  }
67  validateArray(contextExtensions, 'options.contextExtensions');
68  ArrayPrototypeForEach(contextExtensions, (extension, i) => {
69    const name = `options.contextExtensions[${i}]`;
70    validateObject(extension, name, { __proto__: null, nullable: true });
71  });
72
73  const result = compileFunction(
74    code,
75    filename,
76    lineOffset,
77    columnOffset,
78    cachedData,
79    produceCachedData,
80    parsingContext,
81    contextExtensions,
82    params,
83  );
84
85  if (produceCachedData) {
86    result.function.cachedDataProduced = result.cachedDataProduced;
87  }
88
89  if (result.cachedData) {
90    result.function.cachedData = result.cachedData;
91  }
92
93  if (typeof result.cachedDataRejected === 'boolean') {
94    result.function.cachedDataRejected = result.cachedDataRejected;
95  }
96
97  if (importModuleDynamically !== undefined) {
98    validateFunction(importModuleDynamically,
99                     'options.importModuleDynamically');
100    const { importModuleDynamicallyWrap } =
101      require('internal/vm/module');
102    const { callbackMap } = internalBinding('module_wrap');
103    const wrapped = importModuleDynamicallyWrap(importModuleDynamically);
104    const func = result.function;
105    callbackMap.set(result.cacheKey, {
106      importModuleDynamically: (s, _k, i) => wrapped(s, func, i),
107    });
108  }
109
110  return result;
111}
112
113module.exports = {
114  internalCompileFunction,
115  isContext,
116};
117