11'use strict' ;
22
33const {
4- ArrayPrototypeForEach ,
4+ ReflectApply ,
55 Symbol,
66} = primordials ;
77
88const {
9+ ContextifyScript,
910 compileFunction,
1011 isContext : _isContext ,
1112} = internalBinding ( 'contextify' ) ;
13+ const {
14+ runInContext,
15+ } = ContextifyScript . prototype ;
1216const {
1317 default_host_defined_options,
1418} = internalBinding ( 'symbols' ) ;
1519const {
16- validateArray,
17- validateBoolean,
18- validateBuffer,
1920 validateFunction,
2021 validateObject,
21- validateString,
22- validateStringArray,
2322 kValidateObjectAllowArray,
24- kValidateObjectAllowNullable,
25- validateInt32,
2623} = require ( 'internal/validators' ) ;
27- const {
28- ERR_INVALID_ARG_TYPE ,
29- } = require ( 'internal/errors' ) . codes ;
3024
3125function isContext ( object ) {
3226 validateObject ( object , 'object' , kValidateObjectAllowArray ) ;
@@ -50,49 +44,20 @@ function getHostDefinedOptionId(importModuleDynamically, filename) {
5044 return Symbol ( filename ) ;
5145}
5246
53- function internalCompileFunction ( code , params , options ) {
54- validateString ( code , 'code' ) ;
55- if ( params !== undefined ) {
56- validateStringArray ( params , 'params' ) ;
57- }
58- const {
59- filename = '' ,
60- columnOffset = 0 ,
61- lineOffset = 0 ,
62- cachedData = undefined ,
63- produceCachedData = false ,
64- parsingContext = undefined ,
65- contextExtensions = [ ] ,
66- importModuleDynamically,
67- } = options ;
68-
69- validateString ( filename , 'options.filename' ) ;
70- validateInt32 ( columnOffset , 'options.columnOffset' ) ;
71- validateInt32 ( lineOffset , 'options.lineOffset' ) ;
72- if ( cachedData !== undefined )
73- validateBuffer ( cachedData , 'options.cachedData' ) ;
74- validateBoolean ( produceCachedData , 'options.produceCachedData' ) ;
75- if ( parsingContext !== undefined ) {
76- if (
77- typeof parsingContext !== 'object' ||
78- parsingContext === null ||
79- ! isContext ( parsingContext )
80- ) {
81- throw new ERR_INVALID_ARG_TYPE (
82- 'options.parsingContext' ,
83- 'Context' ,
84- parsingContext ,
85- ) ;
86- }
87- }
88- validateArray ( contextExtensions , 'options.contextExtensions' ) ;
89- ArrayPrototypeForEach ( contextExtensions , ( extension , i ) => {
90- const name = `options.contextExtensions[${ i } ]` ;
91- validateObject ( extension , name , kValidateObjectAllowNullable ) ;
47+ function registerImportModuleDynamically ( referrer , importModuleDynamically ) {
48+ const { importModuleDynamicallyWrap } = require ( 'internal/vm/module' ) ;
49+ const { registerModule } = require ( 'internal/modules/esm/utils' ) ;
50+ registerModule ( referrer , {
51+ __proto__ : null ,
52+ importModuleDynamically :
53+ importModuleDynamicallyWrap ( importModuleDynamically ) ,
9254 } ) ;
55+ }
9356
94- const hostDefinedOptionId =
95- getHostDefinedOptionId ( importModuleDynamically , filename ) ;
57+ function internalCompileFunction (
58+ code , filename , lineOffset , columnOffset ,
59+ cachedData , produceCachedData , parsingContext , contextExtensions ,
60+ params , hostDefinedOptionId , importModuleDynamically ) {
9661 const result = compileFunction (
9762 code ,
9863 filename ,
@@ -119,23 +84,65 @@ function internalCompileFunction(code, params, options) {
11984 }
12085
12186 if ( importModuleDynamically !== undefined ) {
122- validateFunction ( importModuleDynamically ,
123- 'options.importModuleDynamically' ) ;
124- const { importModuleDynamicallyWrap } = require ( 'internal/vm/module' ) ;
125- const wrapped = importModuleDynamicallyWrap ( importModuleDynamically ) ;
126- const func = result . function ;
127- const { registerModule } = require ( 'internal/modules/esm/utils' ) ;
128- registerModule ( func , {
129- __proto__ : null ,
130- importModuleDynamically : wrapped ,
131- } ) ;
87+ registerImportModuleDynamically ( result . function , importModuleDynamically ) ;
13288 }
13389
13490 return result ;
13591}
13692
93+ function makeContextifyScript ( code ,
94+ filename ,
95+ lineOffset ,
96+ columnOffset ,
97+ cachedData ,
98+ produceCachedData ,
99+ parsingContext ,
100+ hostDefinedOptionId ,
101+ importModuleDynamically ) {
102+ let script ;
103+ // Calling `ReThrow()` on a native TryCatch does not generate a new
104+ // abort-on-uncaught-exception check. A dummy try/catch in JS land
105+ // protects against that.
106+ try { // eslint-disable-line no-useless-catch
107+ script = new ContextifyScript ( code ,
108+ filename ,
109+ lineOffset ,
110+ columnOffset ,
111+ cachedData ,
112+ produceCachedData ,
113+ parsingContext ,
114+ hostDefinedOptionId ) ;
115+ } catch ( e ) {
116+ throw e ; /* node-do-not-add-exception-line */
117+ }
118+
119+ if ( importModuleDynamically !== undefined ) {
120+ registerImportModuleDynamically ( script , importModuleDynamically ) ;
121+ }
122+ return script ;
123+ }
124+
125+ // Internal version of vm.Script.prototype.runInThisContext() which skips
126+ // argument validation.
127+ function runScriptInThisContext ( script , displayErrors , breakOnFirstLine ) {
128+ return ReflectApply (
129+ runInContext ,
130+ script ,
131+ [
132+ null , // sandbox - use current context
133+ - 1 , // timeout
134+ displayErrors , // displayErrors
135+ false , // breakOnSigint
136+ breakOnFirstLine , // breakOnFirstLine
137+ ] ,
138+ ) ;
139+ }
140+
137141module . exports = {
138142 getHostDefinedOptionId,
139143 internalCompileFunction,
140144 isContext,
145+ makeContextifyScript,
146+ registerImportModuleDynamically,
147+ runScriptInThisContext,
141148} ;
0 commit comments