-
Notifications
You must be signed in to change notification settings - Fork 3.4k
/
Copy pathcompiler.mjs
executable file
·126 lines (106 loc) · 4.01 KB
/
compiler.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env node
/**
* @license
* Copyright 2010 The Emscripten Authors
* SPDX-License-Identifier: MIT
*/
// JavaScript compiler, main entry point
import assert from 'node:assert';
import {parseArgs} from 'node:util';
import {
Benchmarker,
applySettings,
loadDefaultSettings,
printErr,
readFile,
} from '../src/utility.mjs';
loadDefaultSettings();
const options = {
help: {type: 'boolean', short: 'h'},
'symbols-only': {type: 'boolean'},
output: {type: 'string', short: 'o'},
};
const {values, positionals} = parseArgs({options, allowPositionals: true});
if (values.help) {
console.log(`\
Main entry point for JS compiler
If no -o file is specified then the generated code is written to stdout.
Usage: compiler.mjs <settings.json> [-o out.js] [--symbols-only]`);
process.exit(0);
}
// Load settings from JSON passed on the command line
let settingsFile = positionals[0];
assert(settingsFile, 'settings file not specified');
if (settingsFile == '-') {
// Read settings json from stdin (FD 0)
settingsFile = 0;
}
const userSettings = JSON.parse(readFile(settingsFile));
applySettings(userSettings);
export const symbolsOnly = values['symbols-only'];
// TODO(sbc): Remove EMCC_BUILD_DIR at some point. It used to be required
// back when ran the JS compiler with overridden CWD.
process.env['EMCC_BUILD_DIR'] = process.cwd();
// In case compiler.mjs is run directly (as in gen_sig_info)
// ALL_INCOMING_MODULE_JS_API might not be populated yet.
if (!ALL_INCOMING_MODULE_JS_API.length) {
ALL_INCOMING_MODULE_JS_API = INCOMING_MODULE_JS_API;
}
EXPORTED_FUNCTIONS = new Set(EXPORTED_FUNCTIONS);
WASM_EXPORTS = new Set(WASM_EXPORTS);
SIDE_MODULE_EXPORTS = new Set(SIDE_MODULE_EXPORTS);
INCOMING_MODULE_JS_API = new Set(INCOMING_MODULE_JS_API);
ALL_INCOMING_MODULE_JS_API = new Set(ALL_INCOMING_MODULE_JS_API);
EXPORTED_RUNTIME_METHODS = new Set(EXPORTED_RUNTIME_METHODS);
WEAK_IMPORTS = new Set(WEAK_IMPORTS);
if (symbolsOnly) {
INCLUDE_FULL_LIBRARY = 1;
}
// Side modules are pure wasm and have no JS
assert(
!SIDE_MODULE || (ASYNCIFY && symbolsOnly),
'JS compiler should only run on side modules if asyncify is used.',
);
// Load compiler code
// We can't use static import statements here because several of these
// file depend on having the settings defined in the global scope (which
// we do dynamically above.
await import('../src/modules.mjs');
await import('../src/parseTools.mjs');
if (!STRICT) {
await import('../src/parseTools_legacy.mjs');
}
const jsifier = await import('../src/jsifier.mjs');
// ===============================
// Main
// ===============================
const B = new Benchmarker();
try {
await jsifier.runJSify(values.output, symbolsOnly);
B.print('glue');
} catch (err) {
if (err.toString().includes('Aborting compilation due to previous errors')) {
// Compiler failed on user error, don't print the stacktrace in this case.
printErr(err);
} else {
// Compiler failed on internal compiler error!
printErr('Internal compiler error JS compiler');
printErr('Please create a bug report at https://github.com/emscripten-core/emscripten/issues/');
printErr(
'with a log of the build and the input files used to run. Exception message: "' +
(err.stack || err),
);
}
// Work around a node.js bug where stdout buffer is not flushed at process exit:
// Instead of process.exit() directly, wait for stdout flush event.
// See https://github.com/joyent/node/issues/1669 and https://github.com/emscripten-core/emscripten/issues/2582
// Workaround is based on https://github.com/RReverser/acorn/commit/50ab143cecc9ed71a2d66f78b4aec3bb2e9844f6
process.stdout.once('drain', () => process.exit(1));
// Make sure to print something to force the drain event to occur, in case the
// stdout buffer was empty.
console.log(' ');
// Work around another node bug where sometimes 'drain' is never fired - make
// another effort to emit the exit status, after a significant delay (if node
// hasn't fired drain by then, give up)
setTimeout(() => process.exit(1), 500);
}