zuzu-js 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cli.js +1 -1
- package/lib/runtime.js +7 -0
- package/lib/transpiler-new/codegen.js +40 -3
- package/modules/std/io.js +16 -0
- package/modules/std/proc.js +19 -3
- package/package.json +1 -1
package/lib/cli.js
CHANGED
|
@@ -254,7 +254,7 @@ function stripShebang( source ) {
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
function printVersion( runtime, verbose ) {
|
|
257
|
-
process.stdout.write( 'zuzu-js version 0.1.
|
|
257
|
+
process.stdout.write( 'zuzu-js version 0.1.2\n' );
|
|
258
258
|
if ( verbose ) {
|
|
259
259
|
process.stdout.write( '\nlib search paths:\n' );
|
|
260
260
|
for ( const p of runtime.getModuleSearchRoots() ) {
|
package/lib/runtime.js
CHANGED
|
@@ -1904,6 +1904,13 @@ function zuzuTypeMatches( value, typeName ) {
|
|
|
1904
1904
|
if ( typeName === 'PairList' ) {
|
|
1905
1905
|
return isPairListLike( value ) ? 1 : 0;
|
|
1906
1906
|
}
|
|
1907
|
+
if ( typeName === 'Exception' ) {
|
|
1908
|
+
const globalType = globalThis.Exception;
|
|
1909
|
+
if ( globalType != null && zuzuInstanceof( value, globalType ) ) {
|
|
1910
|
+
return 1;
|
|
1911
|
+
}
|
|
1912
|
+
return value instanceof Error ? 1 : 0;
|
|
1913
|
+
}
|
|
1907
1914
|
return zuzuTypeof( value ) === typeName ? 1 : 0;
|
|
1908
1915
|
}
|
|
1909
1916
|
if ( typeName === 'BinaryString' ) {
|
|
@@ -32,6 +32,7 @@ function emitProgram( ast, options = {} ) {
|
|
|
32
32
|
...options,
|
|
33
33
|
asyncContext: needsAsyncWrapper && !syncEval,
|
|
34
34
|
asyncNames: new Set( collectAsyncFunctionNames( ast.body ) ),
|
|
35
|
+
evalNames: new Set( [ 'eval', ...collectEvalImportNames( ast.body ) ] ),
|
|
35
36
|
weakStorageNames: new Set( collectWeakDeclaredNames( ast.body ) ),
|
|
36
37
|
scopeNames: new Set( [
|
|
37
38
|
...expressionDeclaredNames,
|
|
@@ -91,6 +92,7 @@ function marshalCaptureNames( node, options = currentEmitContext() ) {
|
|
|
91
92
|
'__file__',
|
|
92
93
|
'__global__',
|
|
93
94
|
'__system__',
|
|
95
|
+
...( options.evalNames || [] ),
|
|
94
96
|
].filter( Boolean ) );
|
|
95
97
|
const localKinds = new Set( [
|
|
96
98
|
'FunctionDeclaration',
|
|
@@ -124,6 +126,21 @@ function marshalCaptureNames( node, options = currentEmitContext() ) {
|
|
|
124
126
|
}
|
|
125
127
|
return;
|
|
126
128
|
}
|
|
129
|
+
if ( value.type === 'TryStatement' ) {
|
|
130
|
+
visit( value.block, value );
|
|
131
|
+
for ( const handler of value.handlers || [] ) {
|
|
132
|
+
const paramName = handler.paramName;
|
|
133
|
+
const hadParam = paramName ? declared.has( paramName ) : false;
|
|
134
|
+
if ( paramName ) {
|
|
135
|
+
declared.add( paramName );
|
|
136
|
+
}
|
|
137
|
+
visit( handler.body, handler );
|
|
138
|
+
if ( paramName && !hadParam ) {
|
|
139
|
+
declared.delete( paramName );
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
127
144
|
if ( value.type === 'VariableUnpackDeclaration' ) {
|
|
128
145
|
visit( value.init, value );
|
|
129
146
|
for ( const entry of bindingEntriesForPattern( value.pattern ) ) {
|
|
@@ -204,6 +221,7 @@ function nestedFunctionOptions( options = {} ) {
|
|
|
204
221
|
syncEval: options.syncEval,
|
|
205
222
|
asyncContext: options.asyncContext,
|
|
206
223
|
asyncNames: options.asyncNames,
|
|
224
|
+
evalNames: options.evalNames,
|
|
207
225
|
weakStorageNames: options.weakStorageNames,
|
|
208
226
|
scopeNames: options.scopeNames,
|
|
209
227
|
bodylessFunctionNames: options.bodylessFunctionNames,
|
|
@@ -898,7 +916,6 @@ function emitImportDeclaration( node, options = {} ) {
|
|
|
898
916
|
if (
|
|
899
917
|
node.source === 'std/eval'
|
|
900
918
|
&& importedName === 'eval'
|
|
901
|
-
&& specifier.local === 'eval'
|
|
902
919
|
) {
|
|
903
920
|
return '';
|
|
904
921
|
}
|
|
@@ -1101,6 +1118,22 @@ function collectAsyncFunctionNames( statements = [] ) {
|
|
|
1101
1118
|
return names;
|
|
1102
1119
|
}
|
|
1103
1120
|
|
|
1121
|
+
function collectEvalImportNames( statements = [] ) {
|
|
1122
|
+
const names = [];
|
|
1123
|
+
for ( const stmt of statements ) {
|
|
1124
|
+
if ( stmt.type !== 'ImportDeclaration' || stmt.source !== 'std/eval' ) {
|
|
1125
|
+
continue;
|
|
1126
|
+
}
|
|
1127
|
+
for ( const specifier of stmt.specifiers || [] ) {
|
|
1128
|
+
const importedName = normalizeImportedName( stmt.source, specifier.imported );
|
|
1129
|
+
if ( importedName === 'eval' && specifier.local ) {
|
|
1130
|
+
names.push( specifier.local );
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
return names;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1104
1137
|
function collectDeclaredNames( statements ) {
|
|
1105
1138
|
const names = [];
|
|
1106
1139
|
for ( const stmt of statements || [] ) {
|
|
@@ -1684,7 +1717,11 @@ function emitCallExpression( node, options = {} ) {
|
|
|
1684
1717
|
const argArray = emitCallArgumentArray( node.arguments );
|
|
1685
1718
|
source = `__zuzu_super_dispatch( __zuzu_super_static__, self, __zuzu_super_class__, __zuzu_super_method__, ${argArray} )`;
|
|
1686
1719
|
}
|
|
1687
|
-
else if (
|
|
1720
|
+
else if (
|
|
1721
|
+
node.callee.type === 'Identifier'
|
|
1722
|
+
&& ( options.evalNames || new Set( [ 'eval' ] ) ).has( node.callee.name )
|
|
1723
|
+
&& node.arguments.length > 0
|
|
1724
|
+
) {
|
|
1688
1725
|
source = emitEvalCall( node.arguments );
|
|
1689
1726
|
}
|
|
1690
1727
|
else if (
|
|
@@ -1968,7 +2005,7 @@ function emitBinaryExpression( node ) {
|
|
|
1968
2005
|
return `__zuzu_ne( ${left}, ${right} )`;
|
|
1969
2006
|
case '!=':
|
|
1970
2007
|
case '≠':
|
|
1971
|
-
return `
|
|
2008
|
+
return `__zuzu_ne( ${left}, ${right} )`;
|
|
1972
2009
|
case '~':
|
|
1973
2010
|
return `__zuzu_match( ${left}, ${right} )`;
|
|
1974
2011
|
case '_':
|
package/modules/std/io.js
CHANGED
|
@@ -389,6 +389,14 @@ class Path {
|
|
|
389
389
|
slurp_utf8_async() {
|
|
390
390
|
return new Task( async () => fs.promises.readFile( this.value, 'utf8' ) );
|
|
391
391
|
}
|
|
392
|
+
append( value ) {
|
|
393
|
+
traceBlockingOperation( 'std/io Path.append' );
|
|
394
|
+
if ( !( value && value.bytes instanceof Uint8Array ) ) {
|
|
395
|
+
throw new Error( `TypeException: Path.append expects BinaryString, got ${typeName( value )}` );
|
|
396
|
+
}
|
|
397
|
+
fs.appendFileSync( this.value, Buffer.from( value.bytes ) );
|
|
398
|
+
return this;
|
|
399
|
+
}
|
|
392
400
|
append_async( value ) {
|
|
393
401
|
return new Task( async () => {
|
|
394
402
|
if ( !( value && value.bytes instanceof Uint8Array ) ) {
|
|
@@ -398,6 +406,14 @@ class Path {
|
|
|
398
406
|
return this;
|
|
399
407
|
} );
|
|
400
408
|
}
|
|
409
|
+
append_utf8( text ) {
|
|
410
|
+
traceBlockingOperation( 'std/io Path.append_utf8' );
|
|
411
|
+
if ( typeof text !== 'string' ) {
|
|
412
|
+
throw new Error( `TypeException: Path.append_utf8 expects String, got ${typeName( text )}` );
|
|
413
|
+
}
|
|
414
|
+
fs.appendFileSync( this.value, text, 'utf8' );
|
|
415
|
+
return this;
|
|
416
|
+
}
|
|
401
417
|
append_utf8_async( text ) {
|
|
402
418
|
return new Task( async () => {
|
|
403
419
|
if ( typeof text !== 'string' ) {
|
package/modules/std/proc.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { spawn, spawnSync } = require( 'node:child_process' );
|
|
4
4
|
const fs = require( 'node:fs' );
|
|
5
|
+
const os = require( 'node:os' );
|
|
5
6
|
const path = require( 'node:path' );
|
|
6
7
|
const { Task, traceBlockingOperation } = require( './task' );
|
|
7
8
|
|
|
@@ -134,12 +135,15 @@ function runCommand( cmd, options = {} ) {
|
|
|
134
135
|
return cwdErrorResult( cmd, options, cwd.error );
|
|
135
136
|
}
|
|
136
137
|
|
|
138
|
+
const stdinDir = fs.mkdtempSync( path.join( os.tmpdir(), 'zuzu-proc-stdin-' ) );
|
|
139
|
+
const stdinPath = path.join( stdinDir, 'stdin' );
|
|
140
|
+
fs.writeFileSync( stdinPath, stdin, 'utf8' );
|
|
141
|
+
const stdinFd = fs.openSync( stdinPath, 'r' );
|
|
137
142
|
const spawnOptions = {
|
|
138
|
-
input: stdin,
|
|
139
143
|
encoding: 'utf8',
|
|
140
144
|
maxBuffer: 10 * 1024 * 1024,
|
|
141
145
|
stdio: [
|
|
142
|
-
|
|
146
|
+
stdinFd,
|
|
143
147
|
captureStdout ? 'pipe' : 'ignore',
|
|
144
148
|
mergeStderr ? 'pipe' : ( captureStderr ? 'pipe' : 'ignore' ),
|
|
145
149
|
],
|
|
@@ -166,7 +170,19 @@ function runCommand( cmd, options = {} ) {
|
|
|
166
170
|
}
|
|
167
171
|
}
|
|
168
172
|
|
|
169
|
-
|
|
173
|
+
let spawned;
|
|
174
|
+
try {
|
|
175
|
+
spawned = spawnSync( cmd[0], cmd.slice( 1 ), spawnOptions );
|
|
176
|
+
}
|
|
177
|
+
finally {
|
|
178
|
+
fs.closeSync( stdinFd );
|
|
179
|
+
try {
|
|
180
|
+
fs.unlinkSync( stdinPath );
|
|
181
|
+
fs.rmdirSync( stdinDir );
|
|
182
|
+
}
|
|
183
|
+
catch ( _err ) {
|
|
184
|
+
}
|
|
185
|
+
}
|
|
170
186
|
const timedOut = spawned.error && spawned.error.code === 'ETIMEDOUT';
|
|
171
187
|
const signal = timedOut
|
|
172
188
|
? 14
|