1- import { Context , Script , createContext } from 'vm' ;
1+ import 'reflect-metadata' ;
2+
3+ import { Script , createContext } from 'vm' ;
24
35import { dirname , join , normalize } from 'path' ;
46
@@ -9,19 +11,15 @@ import {VirtualMachineException} from 'exception';
911import { transpile } from './transpile' ;
1012
1113export class VirtualMachine implements Disposable {
12- private scripts = new Map < string , Script > ( ) ;
14+ private scripts = new Map < string , [ Script , string ] > ( ) ;
1315 private modules = new Map < string , any > ( ) ;
1416
1517 private paths = new Set < string > ( ) ;
1618 private files = new Set < string > ( ) ;
1719
1820 private fileContents = new Map < string , string > ( ) ;
1921
20- private context : Context ;
21-
22- constructor ( ) {
23- this . context = createContext ( { global, require : mid => this . require ( mid ) } ) ;
24- }
22+ private global = { Reflect} ;
2523
2624 read ( filename ) : string {
2725 return this . fileContents . get ( filename ) ;
@@ -39,18 +37,9 @@ export class VirtualMachine implements Disposable {
3937 throw new VirtualMachineException ( `Cannot overwrite existing module '${ normalizedModuleId } '` ) ;
4038 }
4139
42- const preamble = { exports : { } , filename, id : normalizedModuleId } ;
43-
44- const wrappedCode = `(function() {
45- const module = ${ JSON . stringify ( preamble ) } ;
46- const exports = module.exports;
47- ${ code } ;
48- return module.exports;
49- })()` ;
50-
51- const script = new Script ( wrappedCode , { filename, displayErrors : true } ) ;
40+ const script = new Script ( code , { filename, displayErrors : true } ) ;
5241
53- this . scripts . set ( moduleId , script ) ;
42+ this . scripts . set ( moduleId , [ script , filename ] ) ;
5443 }
5544
5645 private requireStack = new Array < string > ( ) ;
@@ -68,17 +57,26 @@ export class VirtualMachine implements Disposable {
6857 if ( script != null ) {
6958 this . requireStack . push ( moduleId ) ;
7059 try {
71- this . modules . set ( normalizedModuleId , this . executeScript ( script , moduleId ) ) ;
60+ const [ executable , filename ] = script ;
61+ moduleResult = this . executeScript ( executable , filename , normalizedModuleId ) ;
62+
63+ this . modules . set ( normalizedModuleId , moduleResult ) ;
7264 }
7365 finally {
7466 this . requireStack . pop ( ) ;
7567 }
7668 }
7769 else {
7870 moduleResult = this . conditionalTranspile ( normalizedModuleId ) ;
71+
7972 this . modules . set ( moduleId , moduleResult ) ;
8073 }
8174 }
75+
76+ if ( moduleResult == null ) {
77+ throw new VirtualMachineException ( `Require of ${ moduleId } (normalized: ${ normalizedModuleId } ) returned null` ) ;
78+ }
79+
8280 return moduleResult ;
8381 }
8482
@@ -99,13 +97,26 @@ export class VirtualMachine implements Disposable {
9997 this . modules . clear ( ) ;
10098 }
10199
102- private executeScript ( script : Script , moduleId : string ) {
100+ private executeScript ( script : Script , filename : string , moduleId : string ) {
103101 try {
104- return script . runInContext ( this . context ) ;
102+ const exports = { } ;
103+
104+ const context = createContext ( {
105+ require : mid => this . require ( mid ) ,
106+ exports,
107+ global : this . global ,
108+ module : { exports, filename, id : moduleId } ,
109+ __filename : filename ,
110+ __dirname : dirname ( filename ) ,
111+ } ) ;
112+
113+ script . runInContext ( context ) ;
114+
115+ return exports ;
105116 }
106117 catch ( exception ) {
107118 throw new VirtualMachineException (
108- `Exception in ${ moduleId } in sandboxed virtual machine: ${ exception . stack } ` , exception ) ;
119+ `Exception in ${ moduleId } in sandboxed virtual machine: ${ exception . toString ( ) } ` , exception ) ;
109120 }
110121 }
111122
@@ -114,26 +125,23 @@ export class VirtualMachine implements Disposable {
114125 }
115126
116127 normalizeModuleId ( to : string ) : string {
117- const stack = this . requireStack ;
118-
119128 if ( / ^ \. / . test ( to ) ) {
120- if ( this . requireStack . length > 0 ) {
129+ const stack = this . requireStack ;
130+ if ( stack . length > 0 ) {
121131 return join ( dirname ( stack [ stack . length - 1 ] ) , to ) ;
122132 }
123- else {
124- throw new VirtualMachineException (
125- `Cannot determine relative path to ${ to } (require stack: ${ stack . join ( ' -> ' ) } )` ) ;
126- }
127133 }
134+
128135 return to ;
129136 }
130137
131138 private conditionalTranspile ( moduleId : string ) {
132- if ( / ^ \ @a n g u l a r / . test ( moduleId ) ) {
139+ if ( / ^ @ a n g u l a r / . test ( moduleId ) ) {
133140 const [ path , code ] = transpile ( moduleId ) ;
134141 this . define ( path , moduleId , code ) ;
135142 return this . require ( moduleId ) ;
136143 }
144+
137145 return require ( moduleId ) ;
138146 }
139147}
0 commit comments