Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/src/shell_minimal.js
6162 views
1
/**
2
* @license
3
* Copyright 2010 The Emscripten Authors
4
* SPDX-License-Identifier: MIT
5
*/
6
7
#include "minimum_runtime_check.js"
8
9
#if MODULARIZE
10
var Module = moduleArg;
11
#elif USE_CLOSURE_COMPILER
12
/** @type{Object} */
13
var Module;
14
// if (!Module) is crucial for Closure Compiler here as it will
15
// otherwise replace every `Module` occurrence with the object below
16
if (!Module) /** @suppress{checkTypes}*/Module =
17
#if AUDIO_WORKLET
18
globalThis.{{{ EXPORT_NAME }}} ||
19
#endif
20
{"__EMSCRIPTEN_PRIVATE_MODULE_EXPORT_NAME_SUBSTITUTION__":1};
21
22
#elif ENVIRONMENT_MAY_BE_NODE || ENVIRONMENT_MAY_BE_SHELL
23
24
// When running on the web we expect Module to be defined externally, in the
25
// HTML. Otherwise we must define it here before its first use
26
// As a small code size optimization, we can use 'globalThis' to refer to the
27
// global scope Module variable.
28
var Module = globalThis.{{{ EXPORT_NAME }}} || {};
29
30
#else
31
var Module = {{{ EXPORT_NAME }}};
32
#endif
33
34
#if ENVIRONMENT_MAY_BE_NODE
35
var ENVIRONMENT_IS_NODE = {{{ nodeDetectionCode() }}};
36
#endif
37
38
#if ENVIRONMENT_MAY_BE_SHELL
39
var ENVIRONMENT_IS_SHELL = !!globalThis.read;
40
#endif
41
42
#if ASSERTIONS || PTHREADS
43
#if !ENVIRONMENT_MAY_BE_NODE && !ENVIRONMENT_MAY_BE_SHELL
44
var ENVIRONMENT_IS_WEB = true
45
#elif ENVIRONMENT.length == 1
46
var ENVIRONMENT_IS_WEB = {{{ ENVIRONMENT[0] === 'web' }}};
47
#elif ENVIRONMENT_MAY_BE_SHELL && ENVIRONMENT_MAY_BE_NODE
48
var ENVIRONMENT_IS_WEB = !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_SHELL;
49
#elif ENVIRONMENT_MAY_BE_SHELL
50
var ENVIRONMENT_IS_WEB = !ENVIRONMENT_IS_SHELL;
51
#else
52
var ENVIRONMENT_IS_WEB = !ENVIRONMENT_IS_NODE;
53
#endif
54
#endif // ASSERTIONS || PTHREADS
55
56
#if ENVIRONMENT_MAY_BE_NODE && (PTHREADS || WASM_WORKERS)
57
if (ENVIRONMENT_IS_NODE) {
58
var worker_threads = require('node:worker_threads');
59
global.Worker = worker_threads.Worker;
60
}
61
#endif
62
63
#if AUDIO_WORKLET
64
var ENVIRONMENT_IS_AUDIO_WORKLET = !!globalThis.AudioWorkletGlobalScope;
65
#endif
66
67
#if AUDIO_WORKLET && WASM_WORKERS
68
var ENVIRONMENT_IS_WASM_WORKER = globalThis.name == 'em-ww' || ENVIRONMENT_IS_AUDIO_WORKLET;
69
#elif WASM_WORKERS
70
var ENVIRONMENT_IS_WASM_WORKER = globalThis.name == 'em-ww';
71
#endif
72
73
#if WASM_WORKERS && ENVIRONMENT_MAY_BE_NODE
74
if (ENVIRONMENT_IS_NODE) {
75
// The way we signal to a worker that it is hosting a pthread is to construct
76
// it with a specific name.
77
ENVIRONMENT_IS_WASM_WORKER = worker_threads['workerData'] == 'em-ww'
78
}
79
#endif
80
81
#if ASSERTIONS && ENVIRONMENT_MAY_BE_NODE && ENVIRONMENT_MAY_BE_SHELL
82
if (ENVIRONMENT_IS_NODE && ENVIRONMENT_IS_SHELL) {
83
throw new Error('unclear environment');
84
}
85
#endif
86
87
// Redefine these in a --pre-js to override behavior. If you would like to
88
// remove out() or err() altogether, you can no-op it out to function() {},
89
// and build with --closure 1 to get Closure optimize out all the uses
90
// altogether.
91
92
#if ENVIRONMENT_MAY_BE_NODE && PTHREADS
93
// Set up the out() and err() hooks, which are how we can print to stdout or
94
// stderr, respectively.
95
// Normally just binding console.log/console.error here works fine, but
96
// under node (with workers) we see missing/out-of-order messages so route
97
// directly to stdout and stderr.
98
// See https://github.com/emscripten-core/emscripten/issues/14804
99
var defaultPrint = console.log.bind(console);
100
var defaultPrintErr = console.error.bind(console);
101
if (ENVIRONMENT_IS_NODE) {
102
var fs = require('node:fs');
103
defaultPrint = (...args) => fs.writeSync(1, args.join(' ') + '\n');
104
defaultPrintErr = (...args) => fs.writeSync(2, args.join(' ') + '\n');
105
}
106
var out = defaultPrint;
107
var err = defaultPrintErr;
108
#else
109
var out = (...args) => console.log(...args);
110
var err = (...args) => console.error(...args);
111
#endif
112
113
// Override this function in a --pre-js file to get a signal for when
114
// compilation is ready. In that callback, call the function run() to start
115
// the program.
116
function ready() {
117
#if MODULARIZE
118
readyPromiseResolve?.(Module);
119
#endif // MODULARIZE
120
#if INVOKE_RUN && HAS_MAIN
121
{{{ runIfMainThread("run();") }}}
122
#elif ASSERTIONS
123
out('ready() called, and INVOKE_RUN=0. The runtime is now ready for you to call run() to invoke application _main(). You can also override ready() in a --pre-js file to get this signal as a callback')
124
#endif
125
#if PTHREADS
126
// This Worker is now ready to host pthreads, tell the main thread we can proceed.
127
if (ENVIRONMENT_IS_PTHREAD) {
128
startWorker();
129
}
130
#endif
131
}
132
133
#if ENVIRONMENT_MAY_BE_NODE
134
var isFileURI = (filename) => filename.startsWith('file://');
135
var readAsync, readBinary;
136
#include "node_shell_read.js"
137
#endif
138
139
#if ENVIRONMENT_MAY_BE_WORKER || PTHREADS
140
var ENVIRONMENT_IS_WORKER = !!globalThis.WorkerGlobalScope;
141
#endif
142
143
#if PTHREADS
144
// MINIMAL_RUNTIME does not support --proxy-to-worker option, so Worker and Pthread environments
145
// coincide.
146
var ENVIRONMENT_IS_PTHREAD = ENVIRONMENT_IS_WORKER && self.name?.startsWith('em-pthread');
147
148
#if !MODULARIZE
149
// In MODULARIZE mode _scriptName needs to be captured already at the very top of the page immediately when the page is parsed, so it is generated there
150
// before the page load. In non-MODULARIZE modes generate it here.
151
var _scriptName = globalThis.document?.currentScript?.src;
152
#endif
153
154
#if ENVIRONMENT_MAY_BE_NODE
155
if (ENVIRONMENT_IS_NODE) {
156
ENVIRONMENT_IS_WORKER = !worker_threads.isMainThread;
157
// Under node we set `workerData` to `em-pthread` to signal that the worker
158
// is hosting a pthread.
159
ENVIRONMENT_IS_PTHREAD = ENVIRONMENT_IS_WORKER && worker_threads['workerData'] == 'em-pthread'
160
#if !EXPORT_ES6
161
_scriptName = __filename;
162
#endif
163
} else
164
#endif // ENVIRONMENT_MAY_BE_NODE
165
if (ENVIRONMENT_IS_WORKER) {
166
_scriptName = self.location.href;
167
}
168
#endif // PTHREADS
169
170
// --pre-jses are emitted after the Module integration code, so that they can
171
// refer to Module (if they choose; they can also define Module)
172
{{{ preJS() }}}
173
174
#if !SINGLE_FILE
175
176
#if PTHREADS
177
if (!ENVIRONMENT_IS_PTHREAD) {
178
#endif
179
180
#if ENVIRONMENT_MAY_BE_NODE && ((WASM == 1 && !WASM2JS) || WASM == 2)
181
// Wasm or Wasm2JS loading:
182
183
if (ENVIRONMENT_IS_NODE) {
184
var fs = require('node:fs');
185
#if WASM == 2
186
if (globalThis.WebAssembly) Module['wasm'] = fs.readFileSync(__dirname + '/{{{ TARGET_BASENAME }}}.wasm');
187
else eval(fs.readFileSync(__dirname + '/{{{ TARGET_BASENAME }}}.wasm.js')+'');
188
#else
189
#if !WASM2JS
190
Module['wasm'] = fs.readFileSync(__dirname + '/{{{ TARGET_BASENAME }}}.wasm');
191
#endif
192
#endif
193
}
194
#endif
195
196
#if ENVIRONMENT_MAY_BE_SHELL && ((WASM == 1 && !WASM2JS) || WASM == 2)
197
if (ENVIRONMENT_IS_SHELL) {
198
#if WASM == 2
199
if (globalThis.WebAssembly) Module['wasm'] = read('{{{ TARGET_BASENAME }}}.wasm', 'binary');
200
else eval(read('{{{ TARGET_BASENAME }}}.wasm.js')+'');
201
#else
202
#if !WASM2JS
203
Module['wasm'] = read('{{{ TARGET_BASENAME }}}.wasm', 'binary');
204
#endif
205
#endif
206
}
207
#endif
208
209
#if PTHREADS
210
}
211
#endif
212
213
#endif // !SINGLE_FILE
214
215
216