11import path = require( "node:path" ) ;
22import { conlog } from "../common" ;
33import { connection } from "../server" ;
4- import Module from "sslc-emscripten-nodefs/sslc.__filename.mjs" ;
5- import WasmBinary from "sslc-emscripten-nodefs/sslc.wasm" ;
4+ import { fork } from "child_process" ;
65
76export async function ssl_compile ( opts : {
87 cwd : string ;
@@ -12,141 +11,76 @@ export async function ssl_compile(opts: {
1211 headersDir : string ;
1312 interactive : boolean ;
1413} ) {
15- let stdout = "" ;
16- let stderr = "" ;
17- try {
18- const instance = await Module ( {
19- print : ( text : string ) => {
20- stdout = stdout + text + "\n" ;
21- } ,
22- printErr : ( text : string ) => {
23- stderr = stderr + text + "\n" ;
24- } ,
25- wasmBinary : WasmBinary ,
26- locateFile : ( path : string ) => {
27- return path ;
28- } ,
29- noInitialRun : true ,
30- } ) ;
31-
32- const hostDirName = crypto . randomUUID ( ) ;
33-
34- instance . FS . mkdir ( "/" + hostDirName ) ;
35-
36- const cwd = path . parse ( opts . cwd ) ;
37-
38- // conlog(`Mounting ${cwd.root} into /${hostDirName}`);
39- instance . FS . mount (
40- // Using NODEFS instead of NODERAWFS because
41- // NODERAWFS caused errors when the same module
42- // runs the second time
43- instance . NODEFS ,
44- {
45- root : cwd . root ,
46- } ,
47- "/" + hostDirName ,
48- ) ;
49- // conlog(`Chdir into ${path.join(cwd.root, hostDirName, cwd.dir, cwd.name)}`);
50- instance . FS . chdir ( path . join ( hostDirName , cwd . dir , cwd . name ) ) ;
51-
52- // Sanity check that file exists because by default
53- // sslc will emit a warning instead of error
54- // conlog("Doing stat on " + opts.inputFileName);
55- instance . FS . stat ( opts . inputFileName ) ;
56-
57- let cmdArgs = opts . options
58- . split ( " " )
59- . map ( ( s ) => s . trim ( ) )
60- . filter ( ( s ) => s ) ;
61-
62- if ( opts . headersDir ) {
63- if ( cmdArgs . find ( ( s ) => s . startsWith ( "-I" ) ) ) {
64- if ( opts . interactive ) {
65- connection . window . showWarningMessage (
66- "Warning: -I switch is used but it will be ignored" ,
67- ) ;
68- }
69- cmdArgs = cmdArgs . filter ( ( s ) => ! s . startsWith ( "-I" ) ) ;
14+ let cmdArgs = opts . options
15+ . split ( " " )
16+ . map ( ( s ) => s . trim ( ) )
17+ . filter ( ( s ) => s ) ;
18+
19+ if ( opts . headersDir ) {
20+ if ( cmdArgs . find ( ( s ) => s . startsWith ( "-I" ) ) ) {
21+ if ( opts . interactive ) {
22+ connection . window . showWarningMessage (
23+ "Warning: -I switch is used but it will be ignored" ,
24+ ) ;
7025 }
71-
72- const headersDir = path . parse ( opts . headersDir ) ;
73-
74- cmdArgs . push (
75- // TODO: This might not work on Windows if headers on another drive
76- // In this case we need to mount the drive into another directory
77- "-I" + path . join ( headersDir . root , hostDirName , headersDir . dir , headersDir . name ) ,
78- ) ;
26+ cmdArgs = cmdArgs . filter ( ( s ) => ! s . startsWith ( "-I" ) ) ;
7927 }
8028
81- cmdArgs . push ( opts . inputFileName , "-o" , opts . outputFileName ) ;
82-
83- const destMtimeBefore = ( ( ) => {
84- try {
85- const stat = instance . FS . stat ( opts . outputFileName ) ;
86- return stat . mtime ;
87- } catch ( e : any ) {
88- return undefined ;
89- }
90- } ) ( ) ;
29+ const headersDir = path . parse ( opts . headersDir ) ;
9130
92- conlog (
93- "ssl_compile:\n" +
94- JSON . stringify (
95- {
96- opts,
97- cmdArgs,
98- } ,
99- null ,
100- 2 ,
101- ) ,
102- ) ;
103-
104- const returnCode = instance . callMain ( cmdArgs ) ;
105-
106- if ( stderr ) {
107- conlog ( "===== stderr =====\n" + stderr ) ;
108- }
109- stdout = stdout . split ( "/" + hostDirName ) . join ( "" ) ; // That's why hostdir is uuid
110- if ( stdout ) {
111- conlog ( "===== stdout =====\n" + stdout ) ;
112- }
113- conlog ( `===== returnCode: ${ returnCode } =====` ) ;
114- conlog ( "===== instance memory is " + instance . HEAP8 . byteLength + " bytes =====" ) ;
115-
116- const destMtimeAfter = ( ( ) => {
117- try {
118- const stat = instance . FS . stat ( opts . outputFileName ) ;
119- return stat . mtime ;
120- } catch ( e : any ) {
121- return undefined ;
122- }
123- } ) ( ) ;
31+ cmdArgs . push ( "-I" + path . join ( headersDir . root , headersDir . dir , headersDir . name ) ) ;
32+ }
12433
125- conlog (
126- `Destination file mtime ${ destMtimeBefore ?. toISOString ( ) } -> ${ destMtimeAfter ?. toISOString ( ) } ` ,
127- ) ;
128- if ( returnCode === 0 && destMtimeBefore === destMtimeAfter ) {
129- // Sanity check. In case if something went wrong with sslc
130- connection . window . showWarningMessage (
131- "Compilation was successful but the output file was not updated" ,
34+ cmdArgs . push ( opts . inputFileName , "-o" , opts . outputFileName ) ;
35+
36+ const p = fork (
37+ path . join ( __dirname , "../node_modules/sslc-emscripten-noderawfs/compiler.mjs" ) ,
38+ cmdArgs ,
39+ {
40+ execArgv : [ ] , // Disable Node.js flags like --inspect
41+ env : { } ,
42+ cwd : opts . cwd ,
43+ silent : true ,
44+ } ,
45+ ) ;
46+
47+ const stdout : string [ ] = [ ] ;
48+ const stderr : string [ ] = [ ] ;
49+ p . stdout ?. on ( "data" , ( data ) => {
50+ const text = data . toString ( ) ;
51+ stdout . push ( text ) ;
52+ } ) ;
53+
54+ p . stderr ?. on ( "data" , ( data ) => {
55+ const text = data . toString ( ) ;
56+ stderr . push ( text ) ;
57+ } ) ;
58+
59+ return new Promise < {
60+ returnCode : number ;
61+ stdout : string ;
62+ stderr : string ;
63+ } > ( ( resolve , reject ) => {
64+ p . on ( "close" , ( code ) => {
65+ conlog (
66+ `ssl_compile:\n` +
67+ JSON . stringify (
68+ {
69+ opts,
70+ cmdArgs,
71+ returnCode : code ,
72+ stdout : stdout . join ( "" ) ,
73+ stderr : stderr . join ( "" ) ,
74+ } ,
75+ null ,
76+ 2 ,
77+ ) ,
13278 ) ;
133- }
134-
135- instance . FS . chdir ( "/" ) ;
136- instance . FS . unmount ( "/" + hostDirName ) ;
137-
138- return {
139- returnCode,
140- stdout,
141- stderr,
142- } ;
143- } catch ( e : any ) {
144- conlog ( `${ e . name } ${ e . message } ` ) ;
145- conlog ( `${ e . stack } ` ) ;
146- return {
147- returnCode : 1 ,
148- stdout : "" ,
149- stderr : `Failed to run sslc: ${ e } ` ,
150- } ;
151- }
79+ resolve ( {
80+ returnCode : code !== null ? code : 1 , // If code is null, assume error
81+ stdout : stdout . join ( "" ) ,
82+ stderr : stderr . join ( "" ) ,
83+ } ) ;
84+ } ) ;
85+ } ) ;
15286}
0 commit comments