11'use strict' ;
22
33const {
4- ArrayPrototypeForEach,
54 Symbol,
5+ ReflectApply,
66} = primordials ;
77
88const {
99 compileFunction,
1010 isContext : _isContext ,
11+ ContextifyScript,
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 ) ;
@@ -51,49 +45,20 @@ function getHostDefinedOptionId(importModuleDynamically, filename) {
5145
5246}
5347
54- function internalCompileFunction ( code , params , options ) {
55- validateString ( code , 'code' ) ;
56- if ( params !== undefined ) {
57- validateStringArray ( params , 'params' ) ;
58- }
59- const {
60- filename = '' ,
61- columnOffset = 0 ,
62- lineOffset = 0 ,
63- cachedData = undefined ,
64- produceCachedData = false ,
65- parsingContext = undefined ,
66- contextExtensions = [ ] ,
67- importModuleDynamically,
68- } = options ;
69-
70- validateString ( filename , 'options.filename' ) ;
71- validateInt32 ( columnOffset , 'options.columnOffset' ) ;
72- validateInt32 ( lineOffset , 'options.lineOffset' ) ;
73- if ( cachedData !== undefined )
74- validateBuffer ( cachedData , 'options.cachedData' ) ;
75- validateBoolean ( produceCachedData , 'options.produceCachedData' ) ;
76- if ( parsingContext !== undefined ) {
77- if (
78- typeof parsingContext !== 'object' ||
79- parsingContext === null ||
80- ! isContext ( parsingContext )
81- ) {
82- throw new ERR_INVALID_ARG_TYPE (
83- 'options.parsingContext' ,
84- 'Context' ,
85- parsingContext ,
86- ) ;
87- }
88- }
89- validateArray ( contextExtensions , 'options.contextExtensions' ) ;
90- ArrayPrototypeForEach ( contextExtensions , ( extension , i ) => {
91- const name = `options.contextExtensions[${ i } ]` ;
92- validateObject ( extension , name , kValidateObjectAllowNullable ) ;
48+ function registerImportModuleDynamically ( referrer , importModuleDynamically ) {
49+ const { importModuleDynamicallyWrap } = require ( 'internal/vm/module' ) ;
50+ const { registerModule } = require ( 'internal/modules/esm/utils' ) ;
51+ registerModule ( referrer , {
52+ __proto__ : null ,
53+ importModuleDynamically :
54+ importModuleDynamicallyWrap ( importModuleDynamically ) ,
9355 } ) ;
56+ }
9457
95- const hostDefinedOptionId =
96- getHostDefinedOptionId ( importModuleDynamically , filename ) ;
58+ function internalCompileFunction (
59+ code , filename , lineOffset , columnOffset ,
60+ cachedData , produceCachedData , parsingContext , contextExtensions ,
61+ params , hostDefinedOptionId , importModuleDynamically ) {
9762 const result = compileFunction (
9863 code ,
9964 filename ,
@@ -120,23 +85,65 @@ function internalCompileFunction(code, params, options) {
12085 }
12186
12287 if ( importModuleDynamically !== undefined ) {
123- validateFunction ( importModuleDynamically ,
124- 'options.importModuleDynamically' ) ;
125- const { importModuleDynamicallyWrap } = require ( 'internal/vm/module' ) ;
126- const wrapped = importModuleDynamicallyWrap ( importModuleDynamically ) ;
127- const func = result . function ;
128- const { registerModule } = require ( 'internal/modules/esm/utils' ) ;
129- registerModule ( func , {
130- __proto__ : null ,
131- importModuleDynamically : wrapped ,
132- } ) ;
88+ registerImportModuleDynamically ( result . function , importModuleDynamically ) ;
13389 }
13490
13591 return result ;
13692}
13793
94+ function makeContextifyScript ( code ,
95+ filename ,
96+ lineOffset ,
97+ columnOffset ,
98+ cachedData ,
99+ produceCachedData ,
100+ parsingContext ,
101+ hostDefinedOptionId ,
102+ importModuleDynamically ) {
103+ let script ;
104+ // Calling `ReThrow()` on a native TryCatch does not generate a new
105+ // abort-on-uncaught-exception check. A dummy try/catch in JS land
106+ // protects against that.
107+ try { // eslint-disable-line no-useless-catch
108+ script = new ContextifyScript ( code ,
109+ filename ,
110+ lineOffset ,
111+ columnOffset ,
112+ cachedData ,
113+ produceCachedData ,
114+ parsingContext ,
115+ hostDefinedOptionId ) ;
116+ } catch ( e ) {
117+ throw e ; /* node-do-not-add-exception-line */
118+ }
119+
120+ if ( importModuleDynamically !== undefined ) {
121+ registerImportModuleDynamically ( script , importModuleDynamically ) ;
122+ }
123+ return script ;
124+ }
125+
126+ // Internal version of vm.Script.prototype.runInThisContext() which skips
127+ // argument validation.
128+ function runScriptInThisContext ( script , displayErrors , breakOnFirstLine ) {
129+ return ReflectApply (
130+ runInContext ,
131+ script ,
132+ [
133+ null , // sandbox - use current context
134+ - 1 , // timeout
135+ displayErrors , // displayErrors
136+ false , // breakOnSigint
137+ breakOnFirstLine , // breakOnFirstLine
138+ ] ,
139+ ) ;
140+ }
141+
138142module . exports = {
139143 internalCompileFunction,
140144 isContext,
141145 getHostDefinedOptionId,
146+ runScriptInThisContext,
147+ registerImportModuleDynamically,
148+ makeContextifyScript,
142149} ;
0 commit comments