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,
23- validateInt32,
2422} = require ( 'internal/validators' ) ;
25- const {
26- ERR_INVALID_ARG_TYPE ,
27- } = require ( 'internal/errors' ) . codes ;
2823
2924function isContext ( object ) {
3025 validateObject ( object , 'object' , { __proto__ : null , allowArray : true } ) ;
@@ -48,49 +43,20 @@ function getHostDefinedOptionId(importModuleDynamically, filename) {
4843 return Symbol ( filename ) ;
4944}
5045
51- function internalCompileFunction ( code , params , options ) {
52- validateString ( code , 'code' ) ;
53- if ( params !== undefined ) {
54- validateStringArray ( params , 'params' ) ;
55- }
56- const {
57- filename = '' ,
58- columnOffset = 0 ,
59- lineOffset = 0 ,
60- cachedData = undefined ,
61- produceCachedData = false ,
62- parsingContext = undefined ,
63- contextExtensions = [ ] ,
64- importModuleDynamically,
65- } = options ;
66-
67- validateString ( filename , 'options.filename' ) ;
68- validateInt32 ( columnOffset , 'options.columnOffset' ) ;
69- validateInt32 ( lineOffset , 'options.lineOffset' ) ;
70- if ( cachedData !== undefined )
71- validateBuffer ( cachedData , 'options.cachedData' ) ;
72- validateBoolean ( produceCachedData , 'options.produceCachedData' ) ;
73- if ( parsingContext !== undefined ) {
74- if (
75- typeof parsingContext !== 'object' ||
76- parsingContext === null ||
77- ! isContext ( parsingContext )
78- ) {
79- throw new ERR_INVALID_ARG_TYPE (
80- 'options.parsingContext' ,
81- 'Context' ,
82- parsingContext ,
83- ) ;
84- }
85- }
86- validateArray ( contextExtensions , 'options.contextExtensions' ) ;
87- ArrayPrototypeForEach ( contextExtensions , ( extension , i ) => {
88- const name = `options.contextExtensions[${ i } ]` ;
89- validateObject ( extension , name , { __proto__ : null , nullable : true } ) ;
46+ function registerImportModuleDynamically ( referrer , importModuleDynamically ) {
47+ const { importModuleDynamicallyWrap } = require ( 'internal/vm/module' ) ;
48+ const { registerModule } = require ( 'internal/modules/esm/utils' ) ;
49+ registerModule ( referrer , {
50+ __proto__ : null ,
51+ importModuleDynamically :
52+ importModuleDynamicallyWrap ( importModuleDynamically ) ,
9053 } ) ;
54+ }
9155
92- const hostDefinedOptionId =
93- getHostDefinedOptionId ( importModuleDynamically , filename ) ;
56+ function internalCompileFunction (
57+ code , filename , lineOffset , columnOffset ,
58+ cachedData , produceCachedData , parsingContext , contextExtensions ,
59+ params , hostDefinedOptionId , importModuleDynamically ) {
9460 const result = compileFunction (
9561 code ,
9662 filename ,
@@ -117,23 +83,65 @@ function internalCompileFunction(code, params, options) {
11783 }
11884
11985 if ( importModuleDynamically !== undefined ) {
120- validateFunction ( importModuleDynamically ,
121- 'options.importModuleDynamically' ) ;
122- const { importModuleDynamicallyWrap } = require ( 'internal/vm/module' ) ;
123- const wrapped = importModuleDynamicallyWrap ( importModuleDynamically ) ;
124- const func = result . function ;
125- const { registerModule } = require ( 'internal/modules/esm/utils' ) ;
126- registerModule ( func , {
127- __proto__ : null ,
128- importModuleDynamically : wrapped ,
129- } ) ;
86+ registerImportModuleDynamically ( result . function , importModuleDynamically ) ;
13087 }
13188
13289 return result ;
13390}
13491
92+ function makeContextifyScript ( code ,
93+ filename ,
94+ lineOffset ,
95+ columnOffset ,
96+ cachedData ,
97+ produceCachedData ,
98+ parsingContext ,
99+ hostDefinedOptionId ,
100+ importModuleDynamically ) {
101+ let script ;
102+ // Calling `ReThrow()` on a native TryCatch does not generate a new
103+ // abort-on-uncaught-exception check. A dummy try/catch in JS land
104+ // protects against that.
105+ try { // eslint-disable-line no-useless-catch
106+ script = new ContextifyScript ( code ,
107+ filename ,
108+ lineOffset ,
109+ columnOffset ,
110+ cachedData ,
111+ produceCachedData ,
112+ parsingContext ,
113+ hostDefinedOptionId ) ;
114+ } catch ( e ) {
115+ throw e ; /* node-do-not-add-exception-line */
116+ }
117+
118+ if ( importModuleDynamically !== undefined ) {
119+ registerImportModuleDynamically ( script , importModuleDynamically ) ;
120+ }
121+ return script ;
122+ }
123+
124+ // Internal version of vm.Script.prototype.runInThisContext() which skips
125+ // argument validation.
126+ function runScriptInThisContext ( script , displayErrors , breakOnFirstLine ) {
127+ return ReflectApply (
128+ runInContext ,
129+ script ,
130+ [
131+ null , // sandbox - use current context
132+ - 1 , // timeout
133+ displayErrors , // displayErrors
134+ false , // breakOnSigint
135+ breakOnFirstLine , // breakOnFirstLine
136+ ] ,
137+ ) ;
138+ }
139+
135140module . exports = {
136141 getHostDefinedOptionId,
137142 internalCompileFunction,
138143 isContext,
144+ makeContextifyScript,
145+ registerImportModuleDynamically,
146+ runScriptInThisContext,
139147} ;
0 commit comments