用于存放学校的作业便于复习。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

5571 lines
210 KiB

  1. // The Module object: Our interface to the outside world. We import
  2. // and export values on it. There are various ways Module can be used:
  3. // 1. Not defined. We create it here
  4. // 2. A function parameter, function(Module) { ..generated code.. }
  5. // 3. pre-run appended it, var Module = {}; ..generated code..
  6. // 4. External script tag defines var Module.
  7. // We need to check if Module already exists (e.g. case 3 above).
  8. // Substitution will be replaced with actual code on later stage of the build,
  9. // this way Closure Compiler will not mangle it (e.g. case 4. above).
  10. // Note that if you want to run closure, and also to use Module
  11. // after the generated code, you will need to define var Module = {};
  12. // before the code. Then that object will be used in the code, and you
  13. // can continue to use Module afterwards as well.
  14. var Module = typeof Module != 'undefined' ? Module : {};
  15. // See https://caniuse.com/mdn-javascript_builtins_object_assign
  16. // --pre-jses are emitted after the Module integration code, so that they can
  17. // refer to Module (if they choose; they can also define Module)
  18. // {{PRE_JSES}}
  19. // Sometimes an existing Module object exists with properties
  20. // meant to overwrite the default module functionality. Here
  21. // we collect those properties and reapply _after_ we configure
  22. // the current environment's defaults to avoid having to be so
  23. // defensive during initialization.
  24. var moduleOverrides = Object.assign({}, Module);
  25. var arguments_ = [];
  26. var thisProgram = './this.program';
  27. var quit_ = (status, toThrow) => {
  28. throw toThrow;
  29. };
  30. // Determine the runtime environment we are in. You can customize this by
  31. // setting the ENVIRONMENT setting at compile time (see settings.js).
  32. // Attempt to auto-detect the environment
  33. var ENVIRONMENT_IS_WEB = typeof window == 'object';
  34. var ENVIRONMENT_IS_WORKER = typeof importScripts == 'function';
  35. // N.b. Electron.js environment is simultaneously a NODE-environment, but
  36. // also a web environment.
  37. var ENVIRONMENT_IS_NODE = typeof process == 'object' && typeof process.versions == 'object' && typeof process.versions.node == 'string';
  38. var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
  39. if (Module['ENVIRONMENT']) {
  40. throw new Error('Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -s ENVIRONMENT=web or -s ENVIRONMENT=node)');
  41. }
  42. // `/` should be present at the end if `scriptDirectory` is not empty
  43. var scriptDirectory = '';
  44. function locateFile(path) {
  45. if (Module['locateFile']) {
  46. return Module['locateFile'](path, scriptDirectory);
  47. }
  48. return scriptDirectory + path;
  49. }
  50. // Hooks that are implemented differently in different runtime environments.
  51. var read_,
  52. readAsync,
  53. readBinary,
  54. setWindowTitle;
  55. // Normally we don't log exceptions but instead let them bubble out the top
  56. // level where the embedding environment (e.g. the browser) can handle
  57. // them.
  58. // However under v8 and node we sometimes exit the process direcly in which case
  59. // its up to use us to log the exception before exiting.
  60. // If we fix https://github.com/emscripten-core/emscripten/issues/15080
  61. // this may no longer be needed under node.
  62. function logExceptionOnExit(e) {
  63. if (e instanceof ExitStatus) return;
  64. let toLog = e;
  65. if (e && typeof e == 'object' && e.stack) {
  66. toLog = [e, e.stack];
  67. }
  68. err('exiting due to exception: ' + toLog);
  69. }
  70. var fs;
  71. var nodePath;
  72. var requireNodeFS;
  73. if (ENVIRONMENT_IS_NODE) {
  74. if (!(typeof process == 'object' && typeof require == 'function')) throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)');
  75. if (ENVIRONMENT_IS_WORKER) {
  76. scriptDirectory = require('path').dirname(scriptDirectory) + '/';
  77. } else {
  78. scriptDirectory = __dirname + '/';
  79. }
  80. // include: node_shell_read.js
  81. requireNodeFS = () => {
  82. // Use nodePath as the indicator for these not being initialized,
  83. // since in some environments a global fs may have already been
  84. // created.
  85. if (!nodePath) {
  86. fs = require('fs');
  87. nodePath = require('path');
  88. }
  89. };
  90. read_ = function shell_read(filename, binary) {
  91. requireNodeFS();
  92. filename = nodePath['normalize'](filename);
  93. return fs.readFileSync(filename, binary ? undefined : 'utf8');
  94. };
  95. readBinary = (filename) => {
  96. var ret = read_(filename, true);
  97. if (!ret.buffer) {
  98. ret = new Uint8Array(ret);
  99. }
  100. assert(ret.buffer);
  101. return ret;
  102. };
  103. readAsync = (filename, onload, onerror) => {
  104. requireNodeFS();
  105. filename = nodePath['normalize'](filename);
  106. fs.readFile(filename, function(err, data) {
  107. if (err) onerror(err);
  108. else onload(data.buffer);
  109. });
  110. };
  111. // end include: node_shell_read.js
  112. if (process['argv'].length > 1) {
  113. thisProgram = process['argv'][1].replace(/\\/g, '/');
  114. }
  115. arguments_ = process['argv'].slice(2);
  116. if (typeof module != 'undefined') {
  117. module['exports'] = Module;
  118. }
  119. process['on']('uncaughtException', function(ex) {
  120. // suppress ExitStatus exceptions from showing an error
  121. if (!(ex instanceof ExitStatus)) {
  122. throw ex;
  123. }
  124. });
  125. // Without this older versions of node (< v15) will log unhandled rejections
  126. // but return 0, which is not normally the desired behaviour. This is
  127. // not be needed with node v15 and about because it is now the default
  128. // behaviour:
  129. // See https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode
  130. process['on']('unhandledRejection', function(reason) { throw reason; });
  131. quit_ = (status, toThrow) => {
  132. if (keepRuntimeAlive()) {
  133. process['exitCode'] = status;
  134. throw toThrow;
  135. }
  136. logExceptionOnExit(toThrow);
  137. process['exit'](status);
  138. };
  139. Module['inspect'] = function () { return '[Emscripten Module object]'; };
  140. } else
  141. if (ENVIRONMENT_IS_SHELL) {
  142. if ((typeof process == 'object' && typeof require === 'function') || typeof window == 'object' || typeof importScripts == 'function') throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)');
  143. if (typeof read != 'undefined') {
  144. read_ = function shell_read(f) {
  145. return read(f);
  146. };
  147. }
  148. readBinary = function readBinary(f) {
  149. let data;
  150. if (typeof readbuffer == 'function') {
  151. return new Uint8Array(readbuffer(f));
  152. }
  153. data = read(f, 'binary');
  154. assert(typeof data == 'object');
  155. return data;
  156. };
  157. readAsync = function readAsync(f, onload, onerror) {
  158. setTimeout(() => onload(readBinary(f)), 0);
  159. };
  160. if (typeof scriptArgs != 'undefined') {
  161. arguments_ = scriptArgs;
  162. } else if (typeof arguments != 'undefined') {
  163. arguments_ = arguments;
  164. }
  165. if (typeof quit == 'function') {
  166. quit_ = (status, toThrow) => {
  167. // Unlike node which has process.exitCode, d8 has no such mechanism. So we
  168. // have no way to set the exit code and then let the program exit with
  169. // that code when it naturally stops running (say, when all setTimeouts
  170. // have completed). For that reason we must call `quit` - the only way to
  171. // set the exit code - but quit also halts immediately, so we need to be
  172. // careful of whether the runtime is alive or not, which is why this code
  173. // path looks different than node. It also has the downside that it will
  174. // halt the entire program when no code remains to run, which means this
  175. // is not friendly for bundling this code into a larger codebase, and for
  176. // that reason the "shell" environment is mainly useful for testing whole
  177. // programs by themselves, basically.
  178. if (runtimeKeepaliveCounter) {
  179. throw toThrow;
  180. }
  181. logExceptionOnExit(toThrow);
  182. quit(status);
  183. };
  184. }
  185. if (typeof print != 'undefined') {
  186. // Prefer to use print/printErr where they exist, as they usually work better.
  187. if (typeof console == 'undefined') console = /** @type{!Console} */({});
  188. console.log = /** @type{!function(this:Console, ...*): undefined} */ (print);
  189. console.warn = console.error = /** @type{!function(this:Console, ...*): undefined} */ (typeof printErr != 'undefined' ? printErr : print);
  190. }
  191. } else
  192. // Note that this includes Node.js workers when relevant (pthreads is enabled).
  193. // Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
  194. // ENVIRONMENT_IS_NODE.
  195. if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
  196. if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled
  197. scriptDirectory = self.location.href;
  198. } else if (typeof document != 'undefined' && document.currentScript) { // web
  199. scriptDirectory = document.currentScript.src;
  200. }
  201. // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
  202. // otherwise, slice off the final part of the url to find the script directory.
  203. // if scriptDirectory does not contain a slash, lastIndexOf will return -1,
  204. // and scriptDirectory will correctly be replaced with an empty string.
  205. // If scriptDirectory contains a query (starting with ?) or a fragment (starting with #),
  206. // they are removed because they could contain a slash.
  207. if (scriptDirectory.indexOf('blob:') !== 0) {
  208. scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf('/')+1);
  209. } else {
  210. scriptDirectory = '';
  211. }
  212. if (!(typeof window == 'object' || typeof importScripts == 'function')) throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)');
  213. // Differentiate the Web Worker from the Node Worker case, as reading must
  214. // be done differently.
  215. {
  216. // include: web_or_worker_shell_read.js
  217. read_ = (url) => {
  218. var xhr = new XMLHttpRequest();
  219. xhr.open('GET', url, false);
  220. xhr.send(null);
  221. return xhr.responseText;
  222. }
  223. if (ENVIRONMENT_IS_WORKER) {
  224. readBinary = (url) => {
  225. var xhr = new XMLHttpRequest();
  226. xhr.open('GET', url, false);
  227. xhr.responseType = 'arraybuffer';
  228. xhr.send(null);
  229. return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));
  230. };
  231. }
  232. readAsync = (url, onload, onerror) => {
  233. var xhr = new XMLHttpRequest();
  234. xhr.open('GET', url, true);
  235. xhr.responseType = 'arraybuffer';
  236. xhr.onload = () => {
  237. if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
  238. onload(xhr.response);
  239. return;
  240. }
  241. onerror();
  242. };
  243. xhr.onerror = onerror;
  244. xhr.send(null);
  245. }
  246. // end include: web_or_worker_shell_read.js
  247. }
  248. setWindowTitle = (title) => document.title = title;
  249. } else
  250. {
  251. throw new Error('environment detection error');
  252. }
  253. var out = Module['print'] || console.log.bind(console);
  254. var err = Module['printErr'] || console.warn.bind(console);
  255. // Merge back in the overrides
  256. Object.assign(Module, moduleOverrides);
  257. // Free the object hierarchy contained in the overrides, this lets the GC
  258. // reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.
  259. moduleOverrides = null;
  260. checkIncomingModuleAPI();
  261. // Emit code to handle expected values on the Module object. This applies Module.x
  262. // to the proper local x. This has two benefits: first, we only emit it if it is
  263. // expected to arrive, and second, by using a local everywhere else that can be
  264. // minified.
  265. if (Module['arguments']) arguments_ = Module['arguments'];legacyModuleProp('arguments', 'arguments_');
  266. if (Module['thisProgram']) thisProgram = Module['thisProgram'];legacyModuleProp('thisProgram', 'thisProgram');
  267. if (Module['quit']) quit_ = Module['quit'];legacyModuleProp('quit', 'quit_');
  268. // perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
  269. // Assertions on removed incoming Module JS APIs.
  270. assert(typeof Module['memoryInitializerPrefixURL'] == 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead');
  271. assert(typeof Module['pthreadMainPrefixURL'] == 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead');
  272. assert(typeof Module['cdInitializerPrefixURL'] == 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead');
  273. assert(typeof Module['filePackagePrefixURL'] == 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead');
  274. assert(typeof Module['read'] == 'undefined', 'Module.read option was removed (modify read_ in JS)');
  275. assert(typeof Module['readAsync'] == 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)');
  276. assert(typeof Module['readBinary'] == 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)');
  277. assert(typeof Module['setWindowTitle'] == 'undefined', 'Module.setWindowTitle option was removed (modify setWindowTitle in JS)');
  278. assert(typeof Module['TOTAL_MEMORY'] == 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY');
  279. legacyModuleProp('read', 'read_');
  280. legacyModuleProp('readAsync', 'readAsync');
  281. legacyModuleProp('readBinary', 'readBinary');
  282. legacyModuleProp('setWindowTitle', 'setWindowTitle');
  283. var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js';
  284. var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js';
  285. var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js';
  286. var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js';
  287. assert(!ENVIRONMENT_IS_SHELL, "shell environment detected but not enabled at build time. Add 'shell' to `-s ENVIRONMENT` to enable.");
  288. var STACK_ALIGN = 16;
  289. var POINTER_SIZE = 4;
  290. function getNativeTypeSize(type) {
  291. switch (type) {
  292. case 'i1': case 'i8': return 1;
  293. case 'i16': return 2;
  294. case 'i32': return 4;
  295. case 'i64': return 8;
  296. case 'float': return 4;
  297. case 'double': return 8;
  298. default: {
  299. if (type[type.length - 1] === '*') {
  300. return POINTER_SIZE;
  301. } else if (type[0] === 'i') {
  302. const bits = Number(type.substr(1));
  303. assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type);
  304. return bits / 8;
  305. } else {
  306. return 0;
  307. }
  308. }
  309. }
  310. }
  311. function warnOnce(text) {
  312. if (!warnOnce.shown) warnOnce.shown = {};
  313. if (!warnOnce.shown[text]) {
  314. warnOnce.shown[text] = 1;
  315. err(text);
  316. }
  317. }
  318. // include: runtime_functions.js
  319. // Wraps a JS function as a wasm function with a given signature.
  320. function convertJsFunctionToWasm(func, sig) {
  321. // If the type reflection proposal is available, use the new
  322. // "WebAssembly.Function" constructor.
  323. // Otherwise, construct a minimal wasm module importing the JS function and
  324. // re-exporting it.
  325. if (typeof WebAssembly.Function == "function") {
  326. var typeNames = {
  327. 'i': 'i32',
  328. 'j': 'i64',
  329. 'f': 'f32',
  330. 'd': 'f64'
  331. };
  332. var type = {
  333. parameters: [],
  334. results: sig[0] == 'v' ? [] : [typeNames[sig[0]]]
  335. };
  336. for (var i = 1; i < sig.length; ++i) {
  337. type.parameters.push(typeNames[sig[i]]);
  338. }
  339. return new WebAssembly.Function(type, func);
  340. }
  341. // The module is static, with the exception of the type section, which is
  342. // generated based on the signature passed in.
  343. var typeSection = [
  344. 0x01, // id: section,
  345. 0x00, // length: 0 (placeholder)
  346. 0x01, // count: 1
  347. 0x60, // form: func
  348. ];
  349. var sigRet = sig.slice(0, 1);
  350. var sigParam = sig.slice(1);
  351. var typeCodes = {
  352. 'i': 0x7f, // i32
  353. 'j': 0x7e, // i64
  354. 'f': 0x7d, // f32
  355. 'd': 0x7c, // f64
  356. };
  357. // Parameters, length + signatures
  358. typeSection.push(sigParam.length);
  359. for (var i = 0; i < sigParam.length; ++i) {
  360. typeSection.push(typeCodes[sigParam[i]]);
  361. }
  362. // Return values, length + signatures
  363. // With no multi-return in MVP, either 0 (void) or 1 (anything else)
  364. if (sigRet == 'v') {
  365. typeSection.push(0x00);
  366. } else {
  367. typeSection = typeSection.concat([0x01, typeCodes[sigRet]]);
  368. }
  369. // Write the overall length of the type section back into the section header
  370. // (excepting the 2 bytes for the section id and length)
  371. typeSection[1] = typeSection.length - 2;
  372. // Rest of the module is static
  373. var bytes = new Uint8Array([
  374. 0x00, 0x61, 0x73, 0x6d, // magic ("\0asm")
  375. 0x01, 0x00, 0x00, 0x00, // version: 1
  376. ].concat(typeSection, [
  377. 0x02, 0x07, // import section
  378. // (import "e" "f" (func 0 (type 0)))
  379. 0x01, 0x01, 0x65, 0x01, 0x66, 0x00, 0x00,
  380. 0x07, 0x05, // export section
  381. // (export "f" (func 0 (type 0)))
  382. 0x01, 0x01, 0x66, 0x00, 0x00,
  383. ]));
  384. // We can compile this wasm module synchronously because it is very small.
  385. // This accepts an import (at "e.f"), that it reroutes to an export (at "f")
  386. var module = new WebAssembly.Module(bytes);
  387. var instance = new WebAssembly.Instance(module, {
  388. 'e': {
  389. 'f': func
  390. }
  391. });
  392. var wrappedFunc = instance.exports['f'];
  393. return wrappedFunc;
  394. }
  395. var freeTableIndexes = [];
  396. // Weak map of functions in the table to their indexes, created on first use.
  397. var functionsInTableMap;
  398. function getEmptyTableSlot() {
  399. // Reuse a free index if there is one, otherwise grow.
  400. if (freeTableIndexes.length) {
  401. return freeTableIndexes.pop();
  402. }
  403. // Grow the table
  404. try {
  405. wasmTable.grow(1);
  406. } catch (err) {
  407. if (!(err instanceof RangeError)) {
  408. throw err;
  409. }
  410. throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.';
  411. }
  412. return wasmTable.length - 1;
  413. }
  414. function updateTableMap(offset, count) {
  415. for (var i = offset; i < offset + count; i++) {
  416. var item = getWasmTableEntry(i);
  417. // Ignore null values.
  418. if (item) {
  419. functionsInTableMap.set(item, i);
  420. }
  421. }
  422. }
  423. /**
  424. * Add a function to the table.
  425. * 'sig' parameter is required if the function being added is a JS function.
  426. * @param {string=} sig
  427. */
  428. function addFunction(func, sig) {
  429. assert(typeof func != 'undefined');
  430. // Check if the function is already in the table, to ensure each function
  431. // gets a unique index. First, create the map if this is the first use.
  432. if (!functionsInTableMap) {
  433. functionsInTableMap = new WeakMap();
  434. updateTableMap(0, wasmTable.length);
  435. }
  436. if (functionsInTableMap.has(func)) {
  437. return functionsInTableMap.get(func);
  438. }
  439. // It's not in the table, add it now.
  440. var ret = getEmptyTableSlot();
  441. // Set the new value.
  442. try {
  443. // Attempting to call this with JS function will cause of table.set() to fail
  444. setWasmTableEntry(ret, func);
  445. } catch (err) {
  446. if (!(err instanceof TypeError)) {
  447. throw err;
  448. }
  449. assert(typeof sig != 'undefined', 'Missing signature argument to addFunction: ' + func);
  450. var wrapped = convertJsFunctionToWasm(func, sig);
  451. setWasmTableEntry(ret, wrapped);
  452. }
  453. functionsInTableMap.set(func, ret);
  454. return ret;
  455. }
  456. function removeFunction(index) {
  457. functionsInTableMap.delete(getWasmTableEntry(index));
  458. freeTableIndexes.push(index);
  459. }
  460. // end include: runtime_functions.js
  461. // include: runtime_debug.js
  462. function legacyModuleProp(prop, newName) {
  463. if (!Object.getOwnPropertyDescriptor(Module, prop)) {
  464. Object.defineProperty(Module, prop, {
  465. configurable: true,
  466. get: function() {
  467. abort('Module.' + prop + ' has been replaced with plain ' + newName + ' (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)');
  468. }
  469. });
  470. }
  471. }
  472. function ignoredModuleProp(prop) {
  473. if (Object.getOwnPropertyDescriptor(Module, prop)) {
  474. abort('`Module.' + prop + '` was supplied but `' + prop + '` not included in INCOMING_MODULE_JS_API');
  475. }
  476. }
  477. function unexportedMessage(sym, isFSSybol) {
  478. var msg = "'" + sym + "' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)";
  479. if (isFSSybol) {
  480. msg += '. Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you';
  481. }
  482. return msg;
  483. }
  484. function unexportedRuntimeSymbol(sym, isFSSybol) {
  485. if (!Object.getOwnPropertyDescriptor(Module, sym)) {
  486. Object.defineProperty(Module, sym, {
  487. configurable: true,
  488. get: function() {
  489. abort(unexportedMessage(sym, isFSSybol));
  490. }
  491. });
  492. }
  493. }
  494. function unexportedRuntimeFunction(sym, isFSSybol) {
  495. if (!Object.getOwnPropertyDescriptor(Module, sym)) {
  496. Module[sym] = () => abort(unexportedMessage(sym, isFSSybol));
  497. }
  498. }
  499. // end include: runtime_debug.js
  500. var tempRet0 = 0;
  501. var setTempRet0 = (value) => { tempRet0 = value; };
  502. var getTempRet0 = () => tempRet0;
  503. // === Preamble library stuff ===
  504. // Documentation for the public APIs defined in this file must be updated in:
  505. // site/source/docs/api_reference/preamble.js.rst
  506. // A prebuilt local version of the documentation is available at:
  507. // site/build/text/docs/api_reference/preamble.js.txt
  508. // You can also build docs locally as HTML or other formats in site/
  509. // An online HTML version (which may be of a different version of Emscripten)
  510. // is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
  511. var wasmBinary;
  512. if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];legacyModuleProp('wasmBinary', 'wasmBinary');
  513. var noExitRuntime = Module['noExitRuntime'] || true;legacyModuleProp('noExitRuntime', 'noExitRuntime');
  514. if (typeof WebAssembly != 'object') {
  515. abort('no native wasm support detected');
  516. }
  517. // include: runtime_safe_heap.js
  518. // In MINIMAL_RUNTIME, setValue() and getValue() are only available when building with safe heap enabled, for heap safety checking.
  519. // In traditional runtime, setValue() and getValue() are always available (although their use is highly discouraged due to perf penalties)
  520. /** @param {number} ptr
  521. @param {number} value
  522. @param {string} type
  523. @param {number|boolean=} noSafe */
  524. function setValue(ptr, value, type = 'i8', noSafe) {
  525. if (type.charAt(type.length-1) === '*') type = 'i32';
  526. switch (type) {
  527. case 'i1': HEAP8[((ptr)>>0)] = value; break;
  528. case 'i8': HEAP8[((ptr)>>0)] = value; break;
  529. case 'i16': HEAP16[((ptr)>>1)] = value; break;
  530. case 'i32': HEAP32[((ptr)>>2)] = value; break;
  531. case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((ptr)>>2)] = tempI64[0],HEAP32[(((ptr)+(4))>>2)] = tempI64[1]); break;
  532. case 'float': HEAPF32[((ptr)>>2)] = value; break;
  533. case 'double': HEAPF64[((ptr)>>3)] = value; break;
  534. default: abort('invalid type for setValue: ' + type);
  535. }
  536. }
  537. /** @param {number} ptr
  538. @param {string} type
  539. @param {number|boolean=} noSafe */
  540. function getValue(ptr, type = 'i8', noSafe) {
  541. if (type.charAt(type.length-1) === '*') type = 'i32';
  542. switch (type) {
  543. case 'i1': return HEAP8[((ptr)>>0)];
  544. case 'i8': return HEAP8[((ptr)>>0)];
  545. case 'i16': return HEAP16[((ptr)>>1)];
  546. case 'i32': return HEAP32[((ptr)>>2)];
  547. case 'i64': return HEAP32[((ptr)>>2)];
  548. case 'float': return HEAPF32[((ptr)>>2)];
  549. case 'double': return Number(HEAPF64[((ptr)>>3)]);
  550. default: abort('invalid type for getValue: ' + type);
  551. }
  552. return null;
  553. }
  554. // end include: runtime_safe_heap.js
  555. // Wasm globals
  556. var wasmMemory;
  557. //========================================
  558. // Runtime essentials
  559. //========================================
  560. // whether we are quitting the application. no code should run after this.
  561. // set in exit() and abort()
  562. var ABORT = false;
  563. // set by exit() and abort(). Passed to 'onExit' handler.
  564. // NOTE: This is also used as the process return code code in shell environments
  565. // but only when noExitRuntime is false.
  566. var EXITSTATUS;
  567. /** @type {function(*, string=)} */
  568. function assert(condition, text) {
  569. if (!condition) {
  570. abort('Assertion failed' + (text ? ': ' + text : ''));
  571. }
  572. }
  573. // Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
  574. function getCFunc(ident) {
  575. var func = Module['_' + ident]; // closure exported function
  576. assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported');
  577. return func;
  578. }
  579. // C calling interface.
  580. /** @param {string|null=} returnType
  581. @param {Array=} argTypes
  582. @param {Arguments|Array=} args
  583. @param {Object=} opts */
  584. function ccall(ident, returnType, argTypes, args, opts) {
  585. // For fast lookup of conversion functions
  586. var toC = {
  587. 'string': function(str) {
  588. var ret = 0;
  589. if (str !== null && str !== undefined && str !== 0) { // null string
  590. // at most 4 bytes per UTF-8 code point, +1 for the trailing '\0'
  591. var len = (str.length << 2) + 1;
  592. ret = stackAlloc(len);
  593. stringToUTF8(str, ret, len);
  594. }
  595. return ret;
  596. },
  597. 'array': function(arr) {
  598. var ret = stackAlloc(arr.length);
  599. writeArrayToMemory(arr, ret);
  600. return ret;
  601. }
  602. };
  603. function convertReturnValue(ret) {
  604. if (returnType === 'string') return UTF8ToString(ret);
  605. if (returnType === 'boolean') return Boolean(ret);
  606. return ret;
  607. }
  608. var func = getCFunc(ident);
  609. var cArgs = [];
  610. var stack = 0;
  611. assert(returnType !== 'array', 'Return type should not be "array".');
  612. if (args) {
  613. for (var i = 0; i < args.length; i++) {
  614. var converter = toC[argTypes[i]];
  615. if (converter) {
  616. if (stack === 0) stack = stackSave();
  617. cArgs[i] = converter(args[i]);
  618. } else {
  619. cArgs[i] = args[i];
  620. }
  621. }
  622. }
  623. var ret = func.apply(null, cArgs);
  624. function onDone(ret) {
  625. if (stack !== 0) stackRestore(stack);
  626. return convertReturnValue(ret);
  627. }
  628. ret = onDone(ret);
  629. return ret;
  630. }
  631. /** @param {string=} returnType
  632. @param {Array=} argTypes
  633. @param {Object=} opts */
  634. function cwrap(ident, returnType, argTypes, opts) {
  635. return function() {
  636. return ccall(ident, returnType, argTypes, arguments, opts);
  637. }
  638. }
  639. // We used to include malloc/free by default in the past. Show a helpful error in
  640. // builds with assertions.
  641. function _free() {
  642. // Show a helpful error since we used to include free by default in the past.
  643. abort("free() called but not included in the build - add '_free' to EXPORTED_FUNCTIONS");
  644. }
  645. // include: runtime_legacy.js
  646. var ALLOC_NORMAL = 0; // Tries to use _malloc()
  647. var ALLOC_STACK = 1; // Lives for the duration of the current function call
  648. /**
  649. * allocate(): This function is no longer used by emscripten but is kept around to avoid
  650. * breaking external users.
  651. * You should normally not use allocate(), and instead allocate
  652. * memory using _malloc()/stackAlloc(), initialize it with
  653. * setValue(), and so forth.
  654. * @param {(Uint8Array|Array<number>)} slab: An array of data.
  655. * @param {number=} allocator : How to allocate memory, see ALLOC_*
  656. */
  657. function allocate(slab, allocator) {
  658. var ret;
  659. assert(typeof allocator == 'number', 'allocate no longer takes a type argument')
  660. assert(typeof slab != 'number', 'allocate no longer takes a number as arg0')
  661. if (allocator == ALLOC_STACK) {
  662. ret = stackAlloc(slab.length);
  663. } else {
  664. ret = _malloc(slab.length);
  665. }
  666. if (!slab.subarray && !slab.slice) {
  667. slab = new Uint8Array(slab);
  668. }
  669. HEAPU8.set(slab, ret);
  670. return ret;
  671. }
  672. // end include: runtime_legacy.js
  673. // include: runtime_strings.js
  674. // runtime_strings.js: Strings related runtime functions that are part of both MINIMAL_RUNTIME and regular runtime.
  675. // Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the given array that contains uint8 values, returns
  676. // a copy of that string as a Javascript String object.
  677. var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf8') : undefined;
  678. /**
  679. * @param {number} idx
  680. * @param {number=} maxBytesToRead
  681. * @return {string}
  682. */
  683. function UTF8ArrayToString(heap, idx, maxBytesToRead) {
  684. var endIdx = idx + maxBytesToRead;
  685. var endPtr = idx;
  686. // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.
  687. // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.
  688. // (As a tiny code save trick, compare endPtr against endIdx using a negation, so that undefined means Infinity)
  689. while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr;
  690. if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) {
  691. return UTF8Decoder.decode(heap.subarray(idx, endPtr));
  692. } else {
  693. var str = '';
  694. // If building with TextDecoder, we have already computed the string length above, so test loop end condition against that
  695. while (idx < endPtr) {
  696. // For UTF8 byte structure, see:
  697. // http://en.wikipedia.org/wiki/UTF-8#Description
  698. // https://www.ietf.org/rfc/rfc2279.txt
  699. // https://tools.ietf.org/html/rfc3629
  700. var u0 = heap[idx++];
  701. if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }
  702. var u1 = heap[idx++] & 63;
  703. if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }
  704. var u2 = heap[idx++] & 63;
  705. if ((u0 & 0xF0) == 0xE0) {
  706. u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
  707. } else {
  708. if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte 0x' + u0.toString(16) + ' encountered when deserializing a UTF-8 string in wasm memory to a JS string!');
  709. u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heap[idx++] & 63);
  710. }
  711. if (u0 < 0x10000) {
  712. str += String.fromCharCode(u0);
  713. } else {
  714. var ch = u0 - 0x10000;
  715. str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
  716. }
  717. }
  718. }
  719. return str;
  720. }
  721. // Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the emscripten HEAP, returns a
  722. // copy of that string as a Javascript String object.
  723. // maxBytesToRead: an optional length that specifies the maximum number of bytes to read. You can omit
  724. // this parameter to scan the string until the first \0 byte. If maxBytesToRead is
  725. // passed, and the string at [ptr, ptr+maxBytesToReadr[ contains a null byte in the
  726. // middle, then the string will cut short at that byte index (i.e. maxBytesToRead will
  727. // not produce a string of exact length [ptr, ptr+maxBytesToRead[)
  728. // N.B. mixing frequent uses of UTF8ToString() with and without maxBytesToRead may
  729. // throw JS JIT optimizations off, so it is worth to consider consistently using one
  730. // style or the other.
  731. /**
  732. * @param {number} ptr
  733. * @param {number=} maxBytesToRead
  734. * @return {string}
  735. */
  736. function UTF8ToString(ptr, maxBytesToRead) {
  737. ;
  738. return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';
  739. }
  740. // Copies the given Javascript String object 'str' to the given byte array at address 'outIdx',
  741. // encoded in UTF8 form and null-terminated. The copy will require at most str.length*4+1 bytes of space in the HEAP.
  742. // Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.
  743. // Parameters:
  744. // str: the Javascript string to copy.
  745. // heap: the array to copy to. Each index in this array is assumed to be one 8-byte element.
  746. // outIdx: The starting offset in the array to begin the copying.
  747. // maxBytesToWrite: The maximum number of bytes this function can write to the array.
  748. // This count should include the null terminator,
  749. // i.e. if maxBytesToWrite=1, only the null terminator will be written and nothing else.
  750. // maxBytesToWrite=0 does not write any bytes to the output, not even the null terminator.
  751. // Returns the number of bytes written, EXCLUDING the null terminator.
  752. function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
  753. if (!(maxBytesToWrite > 0)) // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes.
  754. return 0;
  755. var startIdx = outIdx;
  756. var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.
  757. for (var i = 0; i < str.length; ++i) {
  758. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8.
  759. // See http://unicode.org/faq/utf_bom.html#utf16-3
  760. // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629
  761. var u = str.charCodeAt(i); // possibly a lead surrogate
  762. if (u >= 0xD800 && u <= 0xDFFF) {
  763. var u1 = str.charCodeAt(++i);
  764. u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF);
  765. }
  766. if (u <= 0x7F) {
  767. if (outIdx >= endIdx) break;
  768. heap[outIdx++] = u;
  769. } else if (u <= 0x7FF) {
  770. if (outIdx + 1 >= endIdx) break;
  771. heap[outIdx++] = 0xC0 | (u >> 6);
  772. heap[outIdx++] = 0x80 | (u & 63);
  773. } else if (u <= 0xFFFF) {
  774. if (outIdx + 2 >= endIdx) break;
  775. heap[outIdx++] = 0xE0 | (u >> 12);
  776. heap[outIdx++] = 0x80 | ((u >> 6) & 63);
  777. heap[outIdx++] = 0x80 | (u & 63);
  778. } else {
  779. if (outIdx + 3 >= endIdx) break;
  780. if (u > 0x10FFFF) warnOnce('Invalid Unicode code point 0x' + u.toString(16) + ' encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).');
  781. heap[outIdx++] = 0xF0 | (u >> 18);
  782. heap[outIdx++] = 0x80 | ((u >> 12) & 63);
  783. heap[outIdx++] = 0x80 | ((u >> 6) & 63);
  784. heap[outIdx++] = 0x80 | (u & 63);
  785. }
  786. }
  787. // Null-terminate the pointer to the buffer.
  788. heap[outIdx] = 0;
  789. return outIdx - startIdx;
  790. }
  791. // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
  792. // null-terminated and encoded in UTF8 form. The copy will require at most str.length*4+1 bytes of space in the HEAP.
  793. // Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.
  794. // Returns the number of bytes written, EXCLUDING the null terminator.
  795. function stringToUTF8(str, outPtr, maxBytesToWrite) {
  796. assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');
  797. return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite);
  798. }
  799. // Returns the number of bytes the given Javascript string takes if encoded as a UTF8 byte array, EXCLUDING the null terminator byte.
  800. function lengthBytesUTF8(str) {
  801. var len = 0;
  802. for (var i = 0; i < str.length; ++i) {
  803. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8.
  804. // See http://unicode.org/faq/utf_bom.html#utf16-3
  805. var u = str.charCodeAt(i); // possibly a lead surrogate
  806. if (u >= 0xD800 && u <= 0xDFFF) u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF);
  807. if (u <= 0x7F) ++len;
  808. else if (u <= 0x7FF) len += 2;
  809. else if (u <= 0xFFFF) len += 3;
  810. else len += 4;
  811. }
  812. return len;
  813. }
  814. // end include: runtime_strings.js
  815. // include: runtime_strings_extra.js
  816. // runtime_strings_extra.js: Strings related runtime functions that are available only in regular runtime.
  817. // Given a pointer 'ptr' to a null-terminated ASCII-encoded string in the emscripten HEAP, returns
  818. // a copy of that string as a Javascript String object.
  819. function AsciiToString(ptr) {
  820. var str = '';
  821. while (1) {
  822. var ch = HEAPU8[((ptr++)>>0)];
  823. if (!ch) return str;
  824. str += String.fromCharCode(ch);
  825. }
  826. }
  827. // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
  828. // null-terminated and encoded in ASCII form. The copy will require at most str.length+1 bytes of space in the HEAP.
  829. function stringToAscii(str, outPtr) {
  830. return writeAsciiToMemory(str, outPtr, false);
  831. }
  832. // Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
  833. // a copy of that string as a Javascript String object.
  834. var UTF16Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf-16le') : undefined;
  835. function UTF16ToString(ptr, maxBytesToRead) {
  836. assert(ptr % 2 == 0, 'Pointer passed to UTF16ToString must be aligned to two bytes!');
  837. var endPtr = ptr;
  838. // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.
  839. // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.
  840. var idx = endPtr >> 1;
  841. var maxIdx = idx + maxBytesToRead / 2;
  842. // If maxBytesToRead is not passed explicitly, it will be undefined, and this
  843. // will always evaluate to true. This saves on code size.
  844. while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx;
  845. endPtr = idx << 1;
  846. if (endPtr - ptr > 32 && UTF16Decoder) {
  847. return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr));
  848. } else {
  849. var str = '';
  850. // If maxBytesToRead is not passed explicitly, it will be undefined, and the for-loop's condition
  851. // will always evaluate to true. The loop is then terminated on the first null char.
  852. for (var i = 0; !(i >= maxBytesToRead / 2); ++i) {
  853. var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
  854. if (codeUnit == 0) break;
  855. // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
  856. str += String.fromCharCode(codeUnit);
  857. }
  858. return str;
  859. }
  860. }
  861. // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
  862. // null-terminated and encoded in UTF16 form. The copy will require at most str.length*4+2 bytes of space in the HEAP.
  863. // Use the function lengthBytesUTF16() to compute the exact number of bytes (excluding null terminator) that this function will write.
  864. // Parameters:
  865. // str: the Javascript string to copy.
  866. // outPtr: Byte address in Emscripten HEAP where to write the string to.
  867. // maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
  868. // terminator, i.e. if maxBytesToWrite=2, only the null terminator will be written and nothing else.
  869. // maxBytesToWrite<2 does not write any bytes to the output, not even the null terminator.
  870. // Returns the number of bytes written, EXCLUDING the null terminator.
  871. function stringToUTF16(str, outPtr, maxBytesToWrite) {
  872. assert(outPtr % 2 == 0, 'Pointer passed to stringToUTF16 must be aligned to two bytes!');
  873. assert(typeof maxBytesToWrite == 'number', 'stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');
  874. // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
  875. if (maxBytesToWrite === undefined) {
  876. maxBytesToWrite = 0x7FFFFFFF;
  877. }
  878. if (maxBytesToWrite < 2) return 0;
  879. maxBytesToWrite -= 2; // Null terminator.
  880. var startPtr = outPtr;
  881. var numCharsToWrite = (maxBytesToWrite < str.length*2) ? (maxBytesToWrite / 2) : str.length;
  882. for (var i = 0; i < numCharsToWrite; ++i) {
  883. // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
  884. var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
  885. HEAP16[((outPtr)>>1)] = codeUnit;
  886. outPtr += 2;
  887. }
  888. // Null-terminate the pointer to the HEAP.
  889. HEAP16[((outPtr)>>1)] = 0;
  890. return outPtr - startPtr;
  891. }
  892. // Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.
  893. function lengthBytesUTF16(str) {
  894. return str.length*2;
  895. }
  896. function UTF32ToString(ptr, maxBytesToRead) {
  897. assert(ptr % 4 == 0, 'Pointer passed to UTF32ToString must be aligned to four bytes!');
  898. var i = 0;
  899. var str = '';
  900. // If maxBytesToRead is not passed explicitly, it will be undefined, and this
  901. // will always evaluate to true. This saves on code size.
  902. while (!(i >= maxBytesToRead / 4)) {
  903. var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
  904. if (utf32 == 0) break;
  905. ++i;
  906. // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
  907. // See http://unicode.org/faq/utf_bom.html#utf16-3
  908. if (utf32 >= 0x10000) {
  909. var ch = utf32 - 0x10000;
  910. str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
  911. } else {
  912. str += String.fromCharCode(utf32);
  913. }
  914. }
  915. return str;
  916. }
  917. // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
  918. // null-terminated and encoded in UTF32 form. The copy will require at most str.length*4+4 bytes of space in the HEAP.
  919. // Use the function lengthBytesUTF32() to compute the exact number of bytes (excluding null terminator) that this function will write.
  920. // Parameters:
  921. // str: the Javascript string to copy.
  922. // outPtr: Byte address in Emscripten HEAP where to write the string to.
  923. // maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
  924. // terminator, i.e. if maxBytesToWrite=4, only the null terminator will be written and nothing else.
  925. // maxBytesToWrite<4 does not write any bytes to the output, not even the null terminator.
  926. // Returns the number of bytes written, EXCLUDING the null terminator.
  927. function stringToUTF32(str, outPtr, maxBytesToWrite) {
  928. assert(outPtr % 4 == 0, 'Pointer passed to stringToUTF32 must be aligned to four bytes!');
  929. assert(typeof maxBytesToWrite == 'number', 'stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');
  930. // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
  931. if (maxBytesToWrite === undefined) {
  932. maxBytesToWrite = 0x7FFFFFFF;
  933. }
  934. if (maxBytesToWrite < 4) return 0;
  935. var startPtr = outPtr;
  936. var endPtr = startPtr + maxBytesToWrite - 4;
  937. for (var i = 0; i < str.length; ++i) {
  938. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
  939. // See http://unicode.org/faq/utf_bom.html#utf16-3
  940. var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
  941. if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
  942. var trailSurrogate = str.charCodeAt(++i);
  943. codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
  944. }
  945. HEAP32[((outPtr)>>2)] = codeUnit;
  946. outPtr += 4;
  947. if (outPtr + 4 > endPtr) break;
  948. }
  949. // Null-terminate the pointer to the HEAP.
  950. HEAP32[((outPtr)>>2)] = 0;
  951. return outPtr - startPtr;
  952. }
  953. // Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.
  954. function lengthBytesUTF32(str) {
  955. var len = 0;
  956. for (var i = 0; i < str.length; ++i) {
  957. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
  958. // See http://unicode.org/faq/utf_bom.html#utf16-3
  959. var codeUnit = str.charCodeAt(i);
  960. if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) ++i; // possibly a lead surrogate, so skip over the tail surrogate.
  961. len += 4;
  962. }
  963. return len;
  964. }
  965. // Allocate heap space for a JS string, and write it there.
  966. // It is the responsibility of the caller to free() that memory.
  967. function allocateUTF8(str) {
  968. var size = lengthBytesUTF8(str) + 1;
  969. var ret = _malloc(size);
  970. if (ret) stringToUTF8Array(str, HEAP8, ret, size);
  971. return ret;
  972. }
  973. // Allocate stack space for a JS string, and write it there.
  974. function allocateUTF8OnStack(str) {
  975. var size = lengthBytesUTF8(str) + 1;
  976. var ret = stackAlloc(size);
  977. stringToUTF8Array(str, HEAP8, ret, size);
  978. return ret;
  979. }
  980. // Deprecated: This function should not be called because it is unsafe and does not provide
  981. // a maximum length limit of how many bytes it is allowed to write. Prefer calling the
  982. // function stringToUTF8Array() instead, which takes in a maximum length that can be used
  983. // to be secure from out of bounds writes.
  984. /** @deprecated
  985. @param {boolean=} dontAddNull */
  986. function writeStringToMemory(string, buffer, dontAddNull) {
  987. warnOnce('writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!');
  988. var /** @type {number} */ lastChar, /** @type {number} */ end;
  989. if (dontAddNull) {
  990. // stringToUTF8Array always appends null. If we don't want to do that, remember the
  991. // character that existed at the location where the null will be placed, and restore
  992. // that after the write (below).
  993. end = buffer + lengthBytesUTF8(string);
  994. lastChar = HEAP8[end];
  995. }
  996. stringToUTF8(string, buffer, Infinity);
  997. if (dontAddNull) HEAP8[end] = lastChar; // Restore the value under the null character.
  998. }
  999. function writeArrayToMemory(array, buffer) {
  1000. assert(array.length >= 0, 'writeArrayToMemory array must have a length (should be an array or typed array)')
  1001. HEAP8.set(array, buffer);
  1002. }
  1003. /** @param {boolean=} dontAddNull */
  1004. function writeAsciiToMemory(str, buffer, dontAddNull) {
  1005. for (var i = 0; i < str.length; ++i) {
  1006. assert(str.charCodeAt(i) === (str.charCodeAt(i) & 0xff));
  1007. HEAP8[((buffer++)>>0)] = str.charCodeAt(i);
  1008. }
  1009. // Null-terminate the pointer to the HEAP.
  1010. if (!dontAddNull) HEAP8[((buffer)>>0)] = 0;
  1011. }
  1012. // end include: runtime_strings_extra.js
  1013. // Memory management
  1014. var HEAP,
  1015. /** @type {!ArrayBuffer} */
  1016. buffer,
  1017. /** @type {!Int8Array} */
  1018. HEAP8,
  1019. /** @type {!Uint8Array} */
  1020. HEAPU8,
  1021. /** @type {!Int16Array} */
  1022. HEAP16,
  1023. /** @type {!Uint16Array} */
  1024. HEAPU16,
  1025. /** @type {!Int32Array} */
  1026. HEAP32,
  1027. /** @type {!Uint32Array} */
  1028. HEAPU32,
  1029. /** @type {!Float32Array} */
  1030. HEAPF32,
  1031. /** @type {!Float64Array} */
  1032. HEAPF64;
  1033. function updateGlobalBufferAndViews(buf) {
  1034. buffer = buf;
  1035. Module['HEAP8'] = HEAP8 = new Int8Array(buf);
  1036. Module['HEAP16'] = HEAP16 = new Int16Array(buf);
  1037. Module['HEAP32'] = HEAP32 = new Int32Array(buf);
  1038. Module['HEAPU8'] = HEAPU8 = new Uint8Array(buf);
  1039. Module['HEAPU16'] = HEAPU16 = new Uint16Array(buf);
  1040. Module['HEAPU32'] = HEAPU32 = new Uint32Array(buf);
  1041. Module['HEAPF32'] = HEAPF32 = new Float32Array(buf);
  1042. Module['HEAPF64'] = HEAPF64 = new Float64Array(buf);
  1043. }
  1044. var TOTAL_STACK = 5242880;
  1045. if (Module['TOTAL_STACK']) assert(TOTAL_STACK === Module['TOTAL_STACK'], 'the stack size can no longer be determined at runtime')
  1046. var INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 16777216;legacyModuleProp('INITIAL_MEMORY', 'INITIAL_MEMORY');
  1047. assert(INITIAL_MEMORY >= TOTAL_STACK, 'INITIAL_MEMORY should be larger than TOTAL_STACK, was ' + INITIAL_MEMORY + '! (TOTAL_STACK=' + TOTAL_STACK + ')');
  1048. // check for full engine support (use string 'subarray' to avoid closure compiler confusion)
  1049. assert(typeof Int32Array != 'undefined' && typeof Float64Array !== 'undefined' && Int32Array.prototype.subarray != undefined && Int32Array.prototype.set != undefined,
  1050. 'JS engine does not provide full typed array support');
  1051. // If memory is defined in wasm, the user can't provide it.
  1052. assert(!Module['wasmMemory'], 'Use of `wasmMemory` detected. Use -s IMPORTED_MEMORY to define wasmMemory externally');
  1053. assert(INITIAL_MEMORY == 16777216, 'Detected runtime INITIAL_MEMORY setting. Use -s IMPORTED_MEMORY to define wasmMemory dynamically');
  1054. // include: runtime_init_table.js
  1055. // In regular non-RELOCATABLE mode the table is exported
  1056. // from the wasm module and this will be assigned once
  1057. // the exports are available.
  1058. var wasmTable;
  1059. // end include: runtime_init_table.js
  1060. // include: runtime_stack_check.js
  1061. // Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.
  1062. function writeStackCookie() {
  1063. var max = _emscripten_stack_get_end();
  1064. assert((max & 3) == 0);
  1065. // The stack grows downwards
  1066. HEAP32[((max + 4)>>2)] = 0x2135467;
  1067. HEAP32[((max + 8)>>2)] = 0x89BACDFE;
  1068. // Also test the global address 0 for integrity.
  1069. HEAP32[0] = 0x63736d65; /* 'emsc' */
  1070. }
  1071. function checkStackCookie() {
  1072. if (ABORT) return;
  1073. var max = _emscripten_stack_get_end();
  1074. var cookie1 = HEAPU32[((max + 4)>>2)];
  1075. var cookie2 = HEAPU32[((max + 8)>>2)];
  1076. if (cookie1 != 0x2135467 || cookie2 != 0x89BACDFE) {
  1077. abort('Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x2135467, but received 0x' + cookie2.toString(16) + ' 0x' + cookie1.toString(16));
  1078. }
  1079. // Also test the global address 0 for integrity.
  1080. if (HEAP32[0] !== 0x63736d65 /* 'emsc' */) abort('Runtime error: The application has corrupted its heap memory area (address zero)!');
  1081. }
  1082. // end include: runtime_stack_check.js
  1083. // include: runtime_assertions.js
  1084. // Endianness check
  1085. (function() {
  1086. var h16 = new Int16Array(1);
  1087. var h8 = new Int8Array(h16.buffer);
  1088. h16[0] = 0x6373;
  1089. if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian! (Run with -s SUPPORT_BIG_ENDIAN=1 to bypass)';
  1090. })();
  1091. // end include: runtime_assertions.js
  1092. var __ATPRERUN__ = []; // functions called before the runtime is initialized
  1093. var __ATINIT__ = []; // functions called during startup
  1094. var __ATMAIN__ = []; // functions called when main() is to be run
  1095. var __ATEXIT__ = []; // functions called during shutdown
  1096. var __ATPOSTRUN__ = []; // functions called after the main() is called
  1097. var runtimeInitialized = false;
  1098. var runtimeExited = false;
  1099. var runtimeKeepaliveCounter = 0;
  1100. function keepRuntimeAlive() {
  1101. return noExitRuntime || runtimeKeepaliveCounter > 0;
  1102. }
  1103. function preRun() {
  1104. if (Module['preRun']) {
  1105. if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
  1106. while (Module['preRun'].length) {
  1107. addOnPreRun(Module['preRun'].shift());
  1108. }
  1109. }
  1110. callRuntimeCallbacks(__ATPRERUN__);
  1111. }
  1112. function initRuntime() {
  1113. checkStackCookie();
  1114. assert(!runtimeInitialized);
  1115. runtimeInitialized = true;
  1116. if (!Module["noFSInit"] && !FS.init.initialized)
  1117. FS.init();
  1118. FS.ignorePermissions = false;
  1119. TTY.init();
  1120. callRuntimeCallbacks(__ATINIT__);
  1121. }
  1122. function preMain() {
  1123. checkStackCookie();
  1124. callRuntimeCallbacks(__ATMAIN__);
  1125. }
  1126. function exitRuntime() {
  1127. checkStackCookie();
  1128. runtimeExited = true;
  1129. }
  1130. function postRun() {
  1131. checkStackCookie();
  1132. if (Module['postRun']) {
  1133. if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
  1134. while (Module['postRun'].length) {
  1135. addOnPostRun(Module['postRun'].shift());
  1136. }
  1137. }
  1138. callRuntimeCallbacks(__ATPOSTRUN__);
  1139. }
  1140. function addOnPreRun(cb) {
  1141. __ATPRERUN__.unshift(cb);
  1142. }
  1143. function addOnInit(cb) {
  1144. __ATINIT__.unshift(cb);
  1145. }
  1146. function addOnPreMain(cb) {
  1147. __ATMAIN__.unshift(cb);
  1148. }
  1149. function addOnExit(cb) {
  1150. }
  1151. function addOnPostRun(cb) {
  1152. __ATPOSTRUN__.unshift(cb);
  1153. }
  1154. // include: runtime_math.js
  1155. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
  1156. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
  1157. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
  1158. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc
  1159. assert(Math.imul, 'This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
  1160. assert(Math.fround, 'This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
  1161. assert(Math.clz32, 'This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
  1162. assert(Math.trunc, 'This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
  1163. // end include: runtime_math.js
  1164. // A counter of dependencies for calling run(). If we need to
  1165. // do asynchronous work before running, increment this and
  1166. // decrement it. Incrementing must happen in a place like
  1167. // Module.preRun (used by emcc to add file preloading).
  1168. // Note that you can add dependencies in preRun, even though
  1169. // it happens right before run - run will be postponed until
  1170. // the dependencies are met.
  1171. var runDependencies = 0;
  1172. var runDependencyWatcher = null;
  1173. var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
  1174. var runDependencyTracking = {};
  1175. function getUniqueRunDependency(id) {
  1176. var orig = id;
  1177. while (1) {
  1178. if (!runDependencyTracking[id]) return id;
  1179. id = orig + Math.random();
  1180. }
  1181. }
  1182. function addRunDependency(id) {
  1183. runDependencies++;
  1184. if (Module['monitorRunDependencies']) {
  1185. Module['monitorRunDependencies'](runDependencies);
  1186. }
  1187. if (id) {
  1188. assert(!runDependencyTracking[id]);
  1189. runDependencyTracking[id] = 1;
  1190. if (runDependencyWatcher === null && typeof setInterval != 'undefined') {
  1191. // Check for missing dependencies every few seconds
  1192. runDependencyWatcher = setInterval(function() {
  1193. if (ABORT) {
  1194. clearInterval(runDependencyWatcher);
  1195. runDependencyWatcher = null;
  1196. return;
  1197. }
  1198. var shown = false;
  1199. for (var dep in runDependencyTracking) {
  1200. if (!shown) {
  1201. shown = true;
  1202. err('still waiting on run dependencies:');
  1203. }
  1204. err('dependency: ' + dep);
  1205. }
  1206. if (shown) {
  1207. err('(end of list)');
  1208. }
  1209. }, 10000);
  1210. }
  1211. } else {
  1212. err('warning: run dependency added without ID');
  1213. }
  1214. }
  1215. function removeRunDependency(id) {
  1216. runDependencies--;
  1217. if (Module['monitorRunDependencies']) {
  1218. Module['monitorRunDependencies'](runDependencies);
  1219. }
  1220. if (id) {
  1221. assert(runDependencyTracking[id]);
  1222. delete runDependencyTracking[id];
  1223. } else {
  1224. err('warning: run dependency removed without ID');
  1225. }
  1226. if (runDependencies == 0) {
  1227. if (runDependencyWatcher !== null) {
  1228. clearInterval(runDependencyWatcher);
  1229. runDependencyWatcher = null;
  1230. }
  1231. if (dependenciesFulfilled) {
  1232. var callback = dependenciesFulfilled;
  1233. dependenciesFulfilled = null;
  1234. callback(); // can add another dependenciesFulfilled
  1235. }
  1236. }
  1237. }
  1238. Module["preloadedImages"] = {}; // maps url to image data
  1239. Module["preloadedAudios"] = {}; // maps url to audio data
  1240. /** @param {string|number=} what */
  1241. function abort(what) {
  1242. {
  1243. if (Module['onAbort']) {
  1244. Module['onAbort'](what);
  1245. }
  1246. }
  1247. what = 'Aborted(' + what + ')';
  1248. // TODO(sbc): Should we remove printing and leave it up to whoever
  1249. // catches the exception?
  1250. err(what);
  1251. ABORT = true;
  1252. EXITSTATUS = 1;
  1253. // Use a wasm runtime error, because a JS error might be seen as a foreign
  1254. // exception, which means we'd run destructors on it. We need the error to
  1255. // simply make the program stop.
  1256. // Suppress closure compiler warning here. Closure compiler's builtin extern
  1257. // defintion for WebAssembly.RuntimeError claims it takes no arguments even
  1258. // though it can.
  1259. // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.
  1260. /** @suppress {checkTypes} */
  1261. var e = new WebAssembly.RuntimeError(what);
  1262. // Throw the error whether or not MODULARIZE is set because abort is used
  1263. // in code paths apart from instantiation where an exception is expected
  1264. // to be thrown when abort is called.
  1265. throw e;
  1266. }
  1267. // {{MEM_INITIALIZER}}
  1268. // include: memoryprofiler.js
  1269. // end include: memoryprofiler.js
  1270. // include: URIUtils.js
  1271. // Prefix of data URIs emitted by SINGLE_FILE and related options.
  1272. var dataURIPrefix = 'data:application/octet-stream;base64,';
  1273. // Indicates whether filename is a base64 data URI.
  1274. function isDataURI(filename) {
  1275. // Prefix of data URIs emitted by SINGLE_FILE and related options.
  1276. return filename.startsWith(dataURIPrefix);
  1277. }
  1278. // Indicates whether filename is delivered via file protocol (as opposed to http/https)
  1279. function isFileURI(filename) {
  1280. return filename.startsWith('file://');
  1281. }
  1282. // end include: URIUtils.js
  1283. /** @param {boolean=} fixedasm */
  1284. function createExportWrapper(name, fixedasm) {
  1285. return function() {
  1286. var displayName = name;
  1287. var asm = fixedasm;
  1288. if (!fixedasm) {
  1289. asm = Module['asm'];
  1290. }
  1291. assert(runtimeInitialized, 'native function `' + displayName + '` called before runtime initialization');
  1292. assert(!runtimeExited, 'native function `' + displayName + '` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)');
  1293. if (!asm[name]) {
  1294. assert(asm[name], 'exported native function `' + displayName + '` not found');
  1295. }
  1296. return asm[name].apply(null, arguments);
  1297. };
  1298. }
  1299. var wasmBinaryFile;
  1300. wasmBinaryFile = '第七章作业1.wasm';
  1301. if (!isDataURI(wasmBinaryFile)) {
  1302. wasmBinaryFile = locateFile(wasmBinaryFile);
  1303. }
  1304. function getBinary(file) {
  1305. try {
  1306. if (file == wasmBinaryFile && wasmBinary) {
  1307. return new Uint8Array(wasmBinary);
  1308. }
  1309. if (readBinary) {
  1310. return readBinary(file);
  1311. } else {
  1312. throw "both async and sync fetching of the wasm failed";
  1313. }
  1314. }
  1315. catch (err) {
  1316. abort(err);
  1317. }
  1318. }
  1319. function getBinaryPromise() {
  1320. // If we don't have the binary yet, try to to load it asynchronously.
  1321. // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url.
  1322. // See https://github.com/github/fetch/pull/92#issuecomment-140665932
  1323. // Cordova or Electron apps are typically loaded from a file:// url.
  1324. // So use fetch if it is available and the url is not a file, otherwise fall back to XHR.
  1325. if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) {
  1326. if (typeof fetch == 'function'
  1327. && !isFileURI(wasmBinaryFile)
  1328. ) {
  1329. return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) {
  1330. if (!response['ok']) {
  1331. throw "failed to load wasm binary file at '" + wasmBinaryFile + "'";
  1332. }
  1333. return response['arrayBuffer']();
  1334. }).catch(function () {
  1335. return getBinary(wasmBinaryFile);
  1336. });
  1337. }
  1338. else {
  1339. if (readAsync) {
  1340. // fetch is not available or url is file => try XHR (readAsync uses XHR internally)
  1341. return new Promise(function(resolve, reject) {
  1342. readAsync(wasmBinaryFile, function(response) { resolve(new Uint8Array(/** @type{!ArrayBuffer} */(response))) }, reject)
  1343. });
  1344. }
  1345. }
  1346. }
  1347. // Otherwise, getBinary should be able to get it synchronously
  1348. return Promise.resolve().then(function() { return getBinary(wasmBinaryFile); });
  1349. }
  1350. // Create the wasm instance.
  1351. // Receives the wasm imports, returns the exports.
  1352. function createWasm() {
  1353. // prepare imports
  1354. var info = {
  1355. 'env': asmLibraryArg,
  1356. 'wasi_snapshot_preview1': asmLibraryArg,
  1357. };
  1358. // Load the wasm module and create an instance of using native support in the JS engine.
  1359. // handle a generated wasm instance, receiving its exports and
  1360. // performing other necessary setup
  1361. /** @param {WebAssembly.Module=} module*/
  1362. function receiveInstance(instance, module) {
  1363. var exports = instance.exports;
  1364. Module['asm'] = exports;
  1365. wasmMemory = Module['asm']['memory'];
  1366. assert(wasmMemory, "memory not found in wasm exports");
  1367. // This assertion doesn't hold when emscripten is run in --post-link
  1368. // mode.
  1369. // TODO(sbc): Read INITIAL_MEMORY out of the wasm file in post-link mode.
  1370. //assert(wasmMemory.buffer.byteLength === 16777216);
  1371. updateGlobalBufferAndViews(wasmMemory.buffer);
  1372. wasmTable = Module['asm']['__indirect_function_table'];
  1373. assert(wasmTable, "table not found in wasm exports");
  1374. addOnInit(Module['asm']['__wasm_call_ctors']);
  1375. removeRunDependency('wasm-instantiate');
  1376. }
  1377. // we can't run yet (except in a pthread, where we have a custom sync instantiator)
  1378. addRunDependency('wasm-instantiate');
  1379. // Prefer streaming instantiation if available.
  1380. // Async compilation can be confusing when an error on the page overwrites Module
  1381. // (for example, if the order of elements is wrong, and the one defining Module is
  1382. // later), so we save Module and check it later.
  1383. var trueModule = Module;
  1384. function receiveInstantiationResult(result) {
  1385. // 'result' is a ResultObject object which has both the module and instance.
  1386. // receiveInstance() will swap in the exports (to Module.asm) so they can be called
  1387. assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?');
  1388. trueModule = null;
  1389. // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line.
  1390. // When the regression is fixed, can restore the above USE_PTHREADS-enabled path.
  1391. receiveInstance(result['instance']);
  1392. }
  1393. function instantiateArrayBuffer(receiver) {
  1394. return getBinaryPromise().then(function(binary) {
  1395. return WebAssembly.instantiate(binary, info);
  1396. }).then(function (instance) {
  1397. return instance;
  1398. }).then(receiver, function(reason) {
  1399. err('failed to asynchronously prepare wasm: ' + reason);
  1400. // Warn on some common problems.
  1401. if (isFileURI(wasmBinaryFile)) {
  1402. err('warning: Loading from a file URI (' + wasmBinaryFile + ') is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing');
  1403. }
  1404. abort(reason);
  1405. });
  1406. }
  1407. function instantiateAsync() {
  1408. if (!wasmBinary &&
  1409. typeof WebAssembly.instantiateStreaming == 'function' &&
  1410. !isDataURI(wasmBinaryFile) &&
  1411. // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously.
  1412. !isFileURI(wasmBinaryFile) &&
  1413. typeof fetch == 'function') {
  1414. return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) {
  1415. // Suppress closure warning here since the upstream definition for
  1416. // instantiateStreaming only allows Promise<Repsponse> rather than
  1417. // an actual Response.
  1418. // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed.
  1419. /** @suppress {checkTypes} */
  1420. var result = WebAssembly.instantiateStreaming(response, info);
  1421. return result.then(
  1422. receiveInstantiationResult,
  1423. function(reason) {
  1424. // We expect the most common failure cause to be a bad MIME type for the binary,
  1425. // in which case falling back to ArrayBuffer instantiation should work.
  1426. err('wasm streaming compile failed: ' + reason);
  1427. err('falling back to ArrayBuffer instantiation');
  1428. return instantiateArrayBuffer(receiveInstantiationResult);
  1429. });
  1430. });
  1431. } else {
  1432. return instantiateArrayBuffer(receiveInstantiationResult);
  1433. }
  1434. }
  1435. // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
  1436. // to manually instantiate the Wasm module themselves. This allows pages to run the instantiation parallel
  1437. // to any other async startup actions they are performing.
  1438. if (Module['instantiateWasm']) {
  1439. try {
  1440. var exports = Module['instantiateWasm'](info, receiveInstance);
  1441. return exports;
  1442. } catch(e) {
  1443. err('Module.instantiateWasm callback failed with error: ' + e);
  1444. return false;
  1445. }
  1446. }
  1447. instantiateAsync();
  1448. return {}; // no exports yet; we'll fill them in later
  1449. }
  1450. // Globals used by JS i64 conversions (see makeSetValue)
  1451. var tempDouble;
  1452. var tempI64;
  1453. // === Body ===
  1454. var ASM_CONSTS = {
  1455. };
  1456. function callRuntimeCallbacks(callbacks) {
  1457. while (callbacks.length > 0) {
  1458. var callback = callbacks.shift();
  1459. if (typeof callback == 'function') {
  1460. callback(Module); // Pass the module as the first argument.
  1461. continue;
  1462. }
  1463. var func = callback.func;
  1464. if (typeof func == 'number') {
  1465. if (callback.arg === undefined) {
  1466. getWasmTableEntry(func)();
  1467. } else {
  1468. getWasmTableEntry(func)(callback.arg);
  1469. }
  1470. } else {
  1471. func(callback.arg === undefined ? null : callback.arg);
  1472. }
  1473. }
  1474. }
  1475. function withStackSave(f) {
  1476. var stack = stackSave();
  1477. var ret = f();
  1478. stackRestore(stack);
  1479. return ret;
  1480. }
  1481. function demangle(func) {
  1482. warnOnce('warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling');
  1483. return func;
  1484. }
  1485. function demangleAll(text) {
  1486. var regex =
  1487. /\b_Z[\w\d_]+/g;
  1488. return text.replace(regex,
  1489. function(x) {
  1490. var y = demangle(x);
  1491. return x === y ? x : (y + ' [' + x + ']');
  1492. });
  1493. }
  1494. var wasmTableMirror = [];
  1495. function getWasmTableEntry(funcPtr) {
  1496. var func = wasmTableMirror[funcPtr];
  1497. if (!func) {
  1498. if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1;
  1499. wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
  1500. }
  1501. assert(wasmTable.get(funcPtr) == func, "JavaScript-side Wasm function table mirror is out of date!");
  1502. return func;
  1503. }
  1504. function handleException(e) {
  1505. // Certain exception types we do not treat as errors since they are used for
  1506. // internal control flow.
  1507. // 1. ExitStatus, which is thrown by exit()
  1508. // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others
  1509. // that wish to return to JS event loop.
  1510. if (e instanceof ExitStatus || e == 'unwind') {
  1511. return EXITSTATUS;
  1512. }
  1513. quit_(1, e);
  1514. }
  1515. function jsStackTrace() {
  1516. var error = new Error();
  1517. if (!error.stack) {
  1518. // IE10+ special cases: It does have callstack info, but it is only populated if an Error object is thrown,
  1519. // so try that as a special-case.
  1520. try {
  1521. throw new Error();
  1522. } catch(e) {
  1523. error = e;
  1524. }
  1525. if (!error.stack) {
  1526. return '(no stack trace available)';
  1527. }
  1528. }
  1529. return error.stack.toString();
  1530. }
  1531. function setWasmTableEntry(idx, func) {
  1532. wasmTable.set(idx, func);
  1533. wasmTableMirror[idx] = func;
  1534. }
  1535. function stackTrace() {
  1536. var js = jsStackTrace();
  1537. if (Module['extraStackTrace']) js += '\n' + Module['extraStackTrace']();
  1538. return demangleAll(js);
  1539. }
  1540. function ___cxa_allocate_exception(size) {
  1541. // Thrown object is prepended by exception metadata block
  1542. return _malloc(size + 16) + 16;
  1543. }
  1544. /** @constructor */
  1545. function ExceptionInfo(excPtr) {
  1546. this.excPtr = excPtr;
  1547. this.ptr = excPtr - 16;
  1548. this.set_type = function(type) {
  1549. HEAP32[(((this.ptr)+(4))>>2)] = type;
  1550. };
  1551. this.get_type = function() {
  1552. return HEAP32[(((this.ptr)+(4))>>2)];
  1553. };
  1554. this.set_destructor = function(destructor) {
  1555. HEAP32[(((this.ptr)+(8))>>2)] = destructor;
  1556. };
  1557. this.get_destructor = function() {
  1558. return HEAP32[(((this.ptr)+(8))>>2)];
  1559. };
  1560. this.set_refcount = function(refcount) {
  1561. HEAP32[((this.ptr)>>2)] = refcount;
  1562. };
  1563. this.set_caught = function (caught) {
  1564. caught = caught ? 1 : 0;
  1565. HEAP8[(((this.ptr)+(12))>>0)] = caught;
  1566. };
  1567. this.get_caught = function () {
  1568. return HEAP8[(((this.ptr)+(12))>>0)] != 0;
  1569. };
  1570. this.set_rethrown = function (rethrown) {
  1571. rethrown = rethrown ? 1 : 0;
  1572. HEAP8[(((this.ptr)+(13))>>0)] = rethrown;
  1573. };
  1574. this.get_rethrown = function () {
  1575. return HEAP8[(((this.ptr)+(13))>>0)] != 0;
  1576. };
  1577. // Initialize native structure fields. Should be called once after allocated.
  1578. this.init = function(type, destructor) {
  1579. this.set_type(type);
  1580. this.set_destructor(destructor);
  1581. this.set_refcount(0);
  1582. this.set_caught(false);
  1583. this.set_rethrown(false);
  1584. }
  1585. this.add_ref = function() {
  1586. var value = HEAP32[((this.ptr)>>2)];
  1587. HEAP32[((this.ptr)>>2)] = value + 1;
  1588. };
  1589. // Returns true if last reference released.
  1590. this.release_ref = function() {
  1591. var prev = HEAP32[((this.ptr)>>2)];
  1592. HEAP32[((this.ptr)>>2)] = prev - 1;
  1593. assert(prev > 0);
  1594. return prev === 1;
  1595. };
  1596. }
  1597. var exceptionLast = 0;
  1598. var uncaughtExceptionCount = 0;
  1599. function ___cxa_throw(ptr, type, destructor) {
  1600. var info = new ExceptionInfo(ptr);
  1601. // Initialize ExceptionInfo content after it was allocated in __cxa_allocate_exception.
  1602. info.init(type, destructor);
  1603. exceptionLast = ptr;
  1604. uncaughtExceptionCount++;
  1605. throw ptr + " - Exception catching is disabled, this exception cannot be caught. Compile with -s NO_DISABLE_EXCEPTION_CATCHING or -s EXCEPTION_CATCHING_ALLOWED=[..] to catch.";
  1606. }
  1607. function setErrNo(value) {
  1608. HEAP32[((___errno_location())>>2)] = value;
  1609. return value;
  1610. }
  1611. var PATH = {splitPath:function(filename) {
  1612. var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
  1613. return splitPathRe.exec(filename).slice(1);
  1614. },normalizeArray:function(parts, allowAboveRoot) {
  1615. // if the path tries to go above the root, `up` ends up > 0
  1616. var up = 0;
  1617. for (var i = parts.length - 1; i >= 0; i--) {
  1618. var last = parts[i];
  1619. if (last === '.') {
  1620. parts.splice(i, 1);
  1621. } else if (last === '..') {
  1622. parts.splice(i, 1);
  1623. up++;
  1624. } else if (up) {
  1625. parts.splice(i, 1);
  1626. up--;
  1627. }
  1628. }
  1629. // if the path is allowed to go above the root, restore leading ..s
  1630. if (allowAboveRoot) {
  1631. for (; up; up--) {
  1632. parts.unshift('..');
  1633. }
  1634. }
  1635. return parts;
  1636. },normalize:function(path) {
  1637. var isAbsolute = path.charAt(0) === '/',
  1638. trailingSlash = path.substr(-1) === '/';
  1639. // Normalize the path
  1640. path = PATH.normalizeArray(path.split('/').filter(function(p) {
  1641. return !!p;
  1642. }), !isAbsolute).join('/');
  1643. if (!path && !isAbsolute) {
  1644. path = '.';
  1645. }
  1646. if (path && trailingSlash) {
  1647. path += '/';
  1648. }
  1649. return (isAbsolute ? '/' : '') + path;
  1650. },dirname:function(path) {
  1651. var result = PATH.splitPath(path),
  1652. root = result[0],
  1653. dir = result[1];
  1654. if (!root && !dir) {
  1655. // No dirname whatsoever
  1656. return '.';
  1657. }
  1658. if (dir) {
  1659. // It has a dirname, strip trailing slash
  1660. dir = dir.substr(0, dir.length - 1);
  1661. }
  1662. return root + dir;
  1663. },basename:function(path) {
  1664. // EMSCRIPTEN return '/'' for '/', not an empty string
  1665. if (path === '/') return '/';
  1666. path = PATH.normalize(path);
  1667. path = path.replace(/\/$/, "");
  1668. var lastSlash = path.lastIndexOf('/');
  1669. if (lastSlash === -1) return path;
  1670. return path.substr(lastSlash+1);
  1671. },extname:function(path) {
  1672. return PATH.splitPath(path)[3];
  1673. },join:function() {
  1674. var paths = Array.prototype.slice.call(arguments, 0);
  1675. return PATH.normalize(paths.join('/'));
  1676. },join2:function(l, r) {
  1677. return PATH.normalize(l + '/' + r);
  1678. }};
  1679. function getRandomDevice() {
  1680. if (typeof crypto == 'object' && typeof crypto['getRandomValues'] == 'function') {
  1681. // for modern web browsers
  1682. var randomBuffer = new Uint8Array(1);
  1683. return function() { crypto.getRandomValues(randomBuffer); return randomBuffer[0]; };
  1684. } else
  1685. if (ENVIRONMENT_IS_NODE) {
  1686. // for nodejs with or without crypto support included
  1687. try {
  1688. var crypto_module = require('crypto');
  1689. // nodejs has crypto support
  1690. return function() { return crypto_module['randomBytes'](1)[0]; };
  1691. } catch (e) {
  1692. // nodejs doesn't have crypto support
  1693. }
  1694. }
  1695. // we couldn't find a proper implementation, as Math.random() is not suitable for /dev/random, see emscripten-core/emscripten/pull/7096
  1696. return function() { abort("no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: function(array) { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };"); };
  1697. }
  1698. var PATH_FS = {resolve:function() {
  1699. var resolvedPath = '',
  1700. resolvedAbsolute = false;
  1701. for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
  1702. var path = (i >= 0) ? arguments[i] : FS.cwd();
  1703. // Skip empty and invalid entries
  1704. if (typeof path != 'string') {
  1705. throw new TypeError('Arguments to path.resolve must be strings');
  1706. } else if (!path) {
  1707. return ''; // an invalid portion invalidates the whole thing
  1708. }
  1709. resolvedPath = path + '/' + resolvedPath;
  1710. resolvedAbsolute = path.charAt(0) === '/';
  1711. }
  1712. // At this point the path should be resolved to a full absolute path, but
  1713. // handle relative paths to be safe (might happen when process.cwd() fails)
  1714. resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) {
  1715. return !!p;
  1716. }), !resolvedAbsolute).join('/');
  1717. return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
  1718. },relative:function(from, to) {
  1719. from = PATH_FS.resolve(from).substr(1);
  1720. to = PATH_FS.resolve(to).substr(1);
  1721. function trim(arr) {
  1722. var start = 0;
  1723. for (; start < arr.length; start++) {
  1724. if (arr[start] !== '') break;
  1725. }
  1726. var end = arr.length - 1;
  1727. for (; end >= 0; end--) {
  1728. if (arr[end] !== '') break;
  1729. }
  1730. if (start > end) return [];
  1731. return arr.slice(start, end - start + 1);
  1732. }
  1733. var fromParts = trim(from.split('/'));
  1734. var toParts = trim(to.split('/'));
  1735. var length = Math.min(fromParts.length, toParts.length);
  1736. var samePartsLength = length;
  1737. for (var i = 0; i < length; i++) {
  1738. if (fromParts[i] !== toParts[i]) {
  1739. samePartsLength = i;
  1740. break;
  1741. }
  1742. }
  1743. var outputParts = [];
  1744. for (var i = samePartsLength; i < fromParts.length; i++) {
  1745. outputParts.push('..');
  1746. }
  1747. outputParts = outputParts.concat(toParts.slice(samePartsLength));
  1748. return outputParts.join('/');
  1749. }};
  1750. var TTY = {ttys:[],init:function () {
  1751. // https://github.com/emscripten-core/emscripten/pull/1555
  1752. // if (ENVIRONMENT_IS_NODE) {
  1753. // // currently, FS.init does not distinguish if process.stdin is a file or TTY
  1754. // // device, it always assumes it's a TTY device. because of this, we're forcing
  1755. // // process.stdin to UTF8 encoding to at least make stdin reading compatible
  1756. // // with text files until FS.init can be refactored.
  1757. // process['stdin']['setEncoding']('utf8');
  1758. // }
  1759. },shutdown:function() {
  1760. // https://github.com/emscripten-core/emscripten/pull/1555
  1761. // if (ENVIRONMENT_IS_NODE) {
  1762. // // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
  1763. // // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation
  1764. // // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
  1765. // // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
  1766. // // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
  1767. // process['stdin']['pause']();
  1768. // }
  1769. },register:function(dev, ops) {
  1770. TTY.ttys[dev] = { input: [], output: [], ops: ops };
  1771. FS.registerDevice(dev, TTY.stream_ops);
  1772. },stream_ops:{open:function(stream) {
  1773. var tty = TTY.ttys[stream.node.rdev];
  1774. if (!tty) {
  1775. throw new FS.ErrnoError(43);
  1776. }
  1777. stream.tty = tty;
  1778. stream.seekable = false;
  1779. },close:function(stream) {
  1780. // flush any pending line data
  1781. stream.tty.ops.flush(stream.tty);
  1782. },flush:function(stream) {
  1783. stream.tty.ops.flush(stream.tty);
  1784. },read:function(stream, buffer, offset, length, pos /* ignored */) {
  1785. if (!stream.tty || !stream.tty.ops.get_char) {
  1786. throw new FS.ErrnoError(60);
  1787. }
  1788. var bytesRead = 0;
  1789. for (var i = 0; i < length; i++) {
  1790. var result;
  1791. try {
  1792. result = stream.tty.ops.get_char(stream.tty);
  1793. } catch (e) {
  1794. throw new FS.ErrnoError(29);
  1795. }
  1796. if (result === undefined && bytesRead === 0) {
  1797. throw new FS.ErrnoError(6);
  1798. }
  1799. if (result === null || result === undefined) break;
  1800. bytesRead++;
  1801. buffer[offset+i] = result;
  1802. }
  1803. if (bytesRead) {
  1804. stream.node.timestamp = Date.now();
  1805. }
  1806. return bytesRead;
  1807. },write:function(stream, buffer, offset, length, pos) {
  1808. if (!stream.tty || !stream.tty.ops.put_char) {
  1809. throw new FS.ErrnoError(60);
  1810. }
  1811. try {
  1812. for (var i = 0; i < length; i++) {
  1813. stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
  1814. }
  1815. } catch (e) {
  1816. throw new FS.ErrnoError(29);
  1817. }
  1818. if (length) {
  1819. stream.node.timestamp = Date.now();
  1820. }
  1821. return i;
  1822. }},default_tty_ops:{get_char:function(tty) {
  1823. if (!tty.input.length) {
  1824. var result = null;
  1825. if (ENVIRONMENT_IS_NODE) {
  1826. // we will read data by chunks of BUFSIZE
  1827. var BUFSIZE = 256;
  1828. var buf = Buffer.alloc(BUFSIZE);
  1829. var bytesRead = 0;
  1830. try {
  1831. bytesRead = fs.readSync(process.stdin.fd, buf, 0, BUFSIZE, -1);
  1832. } catch(e) {
  1833. // Cross-platform differences: on Windows, reading EOF throws an exception, but on other OSes,
  1834. // reading EOF returns 0. Uniformize behavior by treating the EOF exception to return 0.
  1835. if (e.toString().includes('EOF')) bytesRead = 0;
  1836. else throw e;
  1837. }
  1838. if (bytesRead > 0) {
  1839. result = buf.slice(0, bytesRead).toString('utf-8');
  1840. } else {
  1841. result = null;
  1842. }
  1843. } else
  1844. if (typeof window != 'undefined' &&
  1845. typeof window.prompt == 'function') {
  1846. // Browser.
  1847. result = window.prompt('Input: '); // returns null on cancel
  1848. if (result !== null) {
  1849. result += '\n';
  1850. }
  1851. } else if (typeof readline == 'function') {
  1852. // Command line.
  1853. result = readline();
  1854. if (result !== null) {
  1855. result += '\n';
  1856. }
  1857. }
  1858. if (!result) {
  1859. return null;
  1860. }
  1861. tty.input = intArrayFromString(result, true);
  1862. }
  1863. return tty.input.shift();
  1864. },put_char:function(tty, val) {
  1865. if (val === null || val === 10) {
  1866. out(UTF8ArrayToString(tty.output, 0));
  1867. tty.output = [];
  1868. } else {
  1869. if (val != 0) tty.output.push(val); // val == 0 would cut text output off in the middle.
  1870. }
  1871. },flush:function(tty) {
  1872. if (tty.output && tty.output.length > 0) {
  1873. out(UTF8ArrayToString(tty.output, 0));
  1874. tty.output = [];
  1875. }
  1876. }},default_tty1_ops:{put_char:function(tty, val) {
  1877. if (val === null || val === 10) {
  1878. err(UTF8ArrayToString(tty.output, 0));
  1879. tty.output = [];
  1880. } else {
  1881. if (val != 0) tty.output.push(val);
  1882. }
  1883. },flush:function(tty) {
  1884. if (tty.output && tty.output.length > 0) {
  1885. err(UTF8ArrayToString(tty.output, 0));
  1886. tty.output = [];
  1887. }
  1888. }}};
  1889. function zeroMemory(address, size) {
  1890. HEAPU8.fill(0, address, address + size);
  1891. }
  1892. function alignMemory(size, alignment) {
  1893. assert(alignment, "alignment argument is required");
  1894. return Math.ceil(size / alignment) * alignment;
  1895. }
  1896. function mmapAlloc(size) {
  1897. abort('internal error: mmapAlloc called but `emscripten_builtin_memalign` native symbol not exported');
  1898. }
  1899. var MEMFS = {ops_table:null,mount:function(mount) {
  1900. return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
  1901. },createNode:function(parent, name, mode, dev) {
  1902. if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
  1903. // no supported
  1904. throw new FS.ErrnoError(63);
  1905. }
  1906. if (!MEMFS.ops_table) {
  1907. MEMFS.ops_table = {
  1908. dir: {
  1909. node: {
  1910. getattr: MEMFS.node_ops.getattr,
  1911. setattr: MEMFS.node_ops.setattr,
  1912. lookup: MEMFS.node_ops.lookup,
  1913. mknod: MEMFS.node_ops.mknod,
  1914. rename: MEMFS.node_ops.rename,
  1915. unlink: MEMFS.node_ops.unlink,
  1916. rmdir: MEMFS.node_ops.rmdir,
  1917. readdir: MEMFS.node_ops.readdir,
  1918. symlink: MEMFS.node_ops.symlink
  1919. },
  1920. stream: {
  1921. llseek: MEMFS.stream_ops.llseek
  1922. }
  1923. },
  1924. file: {
  1925. node: {
  1926. getattr: MEMFS.node_ops.getattr,
  1927. setattr: MEMFS.node_ops.setattr
  1928. },
  1929. stream: {
  1930. llseek: MEMFS.stream_ops.llseek,
  1931. read: MEMFS.stream_ops.read,
  1932. write: MEMFS.stream_ops.write,
  1933. allocate: MEMFS.stream_ops.allocate,
  1934. mmap: MEMFS.stream_ops.mmap,
  1935. msync: MEMFS.stream_ops.msync
  1936. }
  1937. },
  1938. link: {
  1939. node: {
  1940. getattr: MEMFS.node_ops.getattr,
  1941. setattr: MEMFS.node_ops.setattr,
  1942. readlink: MEMFS.node_ops.readlink
  1943. },
  1944. stream: {}
  1945. },
  1946. chrdev: {
  1947. node: {
  1948. getattr: MEMFS.node_ops.getattr,
  1949. setattr: MEMFS.node_ops.setattr
  1950. },
  1951. stream: FS.chrdev_stream_ops
  1952. }
  1953. };
  1954. }
  1955. var node = FS.createNode(parent, name, mode, dev);
  1956. if (FS.isDir(node.mode)) {
  1957. node.node_ops = MEMFS.ops_table.dir.node;
  1958. node.stream_ops = MEMFS.ops_table.dir.stream;
  1959. node.contents = {};
  1960. } else if (FS.isFile(node.mode)) {
  1961. node.node_ops = MEMFS.ops_table.file.node;
  1962. node.stream_ops = MEMFS.ops_table.file.stream;
  1963. node.usedBytes = 0; // The actual number of bytes used in the typed array, as opposed to contents.length which gives the whole capacity.
  1964. // When the byte data of the file is populated, this will point to either a typed array, or a normal JS array. Typed arrays are preferred
  1965. // for performance, and used by default. However, typed arrays are not resizable like normal JS arrays are, so there is a small disk size
  1966. // penalty involved for appending file writes that continuously grow a file similar to std::vector capacity vs used -scheme.
  1967. node.contents = null;
  1968. } else if (FS.isLink(node.mode)) {
  1969. node.node_ops = MEMFS.ops_table.link.node;
  1970. node.stream_ops = MEMFS.ops_table.link.stream;
  1971. } else if (FS.isChrdev(node.mode)) {
  1972. node.node_ops = MEMFS.ops_table.chrdev.node;
  1973. node.stream_ops = MEMFS.ops_table.chrdev.stream;
  1974. }
  1975. node.timestamp = Date.now();
  1976. // add the new node to the parent
  1977. if (parent) {
  1978. parent.contents[name] = node;
  1979. parent.timestamp = node.timestamp;
  1980. }
  1981. return node;
  1982. },getFileDataAsTypedArray:function(node) {
  1983. if (!node.contents) return new Uint8Array(0);
  1984. if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.
  1985. return new Uint8Array(node.contents);
  1986. },expandFileStorage:function(node, newCapacity) {
  1987. var prevCapacity = node.contents ? node.contents.length : 0;
  1988. if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.
  1989. // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.
  1990. // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to
  1991. // avoid overshooting the allocation cap by a very large margin.
  1992. var CAPACITY_DOUBLING_MAX = 1024 * 1024;
  1993. newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>> 0);
  1994. if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.
  1995. var oldContents = node.contents;
  1996. node.contents = new Uint8Array(newCapacity); // Allocate new storage.
  1997. if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); // Copy old data over to the new storage.
  1998. },resizeFileStorage:function(node, newSize) {
  1999. if (node.usedBytes == newSize) return;
  2000. if (newSize == 0) {
  2001. node.contents = null; // Fully decommit when requesting a resize to zero.
  2002. node.usedBytes = 0;
  2003. } else {
  2004. var oldContents = node.contents;
  2005. node.contents = new Uint8Array(newSize); // Allocate new storage.
  2006. if (oldContents) {
  2007. node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
  2008. }
  2009. node.usedBytes = newSize;
  2010. }
  2011. },node_ops:{getattr:function(node) {
  2012. var attr = {};
  2013. // device numbers reuse inode numbers.
  2014. attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
  2015. attr.ino = node.id;
  2016. attr.mode = node.mode;
  2017. attr.nlink = 1;
  2018. attr.uid = 0;
  2019. attr.gid = 0;
  2020. attr.rdev = node.rdev;
  2021. if (FS.isDir(node.mode)) {
  2022. attr.size = 4096;
  2023. } else if (FS.isFile(node.mode)) {
  2024. attr.size = node.usedBytes;
  2025. } else if (FS.isLink(node.mode)) {
  2026. attr.size = node.link.length;
  2027. } else {
  2028. attr.size = 0;
  2029. }
  2030. attr.atime = new Date(node.timestamp);
  2031. attr.mtime = new Date(node.timestamp);
  2032. attr.ctime = new Date(node.timestamp);
  2033. // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
  2034. // but this is not required by the standard.
  2035. attr.blksize = 4096;
  2036. attr.blocks = Math.ceil(attr.size / attr.blksize);
  2037. return attr;
  2038. },setattr:function(node, attr) {
  2039. if (attr.mode !== undefined) {
  2040. node.mode = attr.mode;
  2041. }
  2042. if (attr.timestamp !== undefined) {
  2043. node.timestamp = attr.timestamp;
  2044. }
  2045. if (attr.size !== undefined) {
  2046. MEMFS.resizeFileStorage(node, attr.size);
  2047. }
  2048. },lookup:function(parent, name) {
  2049. throw FS.genericErrors[44];
  2050. },mknod:function(parent, name, mode, dev) {
  2051. return MEMFS.createNode(parent, name, mode, dev);
  2052. },rename:function(old_node, new_dir, new_name) {
  2053. // if we're overwriting a directory at new_name, make sure it's empty.
  2054. if (FS.isDir(old_node.mode)) {
  2055. var new_node;
  2056. try {
  2057. new_node = FS.lookupNode(new_dir, new_name);
  2058. } catch (e) {
  2059. }
  2060. if (new_node) {
  2061. for (var i in new_node.contents) {
  2062. throw new FS.ErrnoError(55);
  2063. }
  2064. }
  2065. }
  2066. // do the internal rewiring
  2067. delete old_node.parent.contents[old_node.name];
  2068. old_node.parent.timestamp = Date.now()
  2069. old_node.name = new_name;
  2070. new_dir.contents[new_name] = old_node;
  2071. new_dir.timestamp = old_node.parent.timestamp;
  2072. old_node.parent = new_dir;
  2073. },unlink:function(parent, name) {
  2074. delete parent.contents[name];
  2075. parent.timestamp = Date.now();
  2076. },rmdir:function(parent, name) {
  2077. var node = FS.lookupNode(parent, name);
  2078. for (var i in node.contents) {
  2079. throw new FS.ErrnoError(55);
  2080. }
  2081. delete parent.contents[name];
  2082. parent.timestamp = Date.now();
  2083. },readdir:function(node) {
  2084. var entries = ['.', '..'];
  2085. for (var key in node.contents) {
  2086. if (!node.contents.hasOwnProperty(key)) {
  2087. continue;
  2088. }
  2089. entries.push(key);
  2090. }
  2091. return entries;
  2092. },symlink:function(parent, newname, oldpath) {
  2093. var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
  2094. node.link = oldpath;
  2095. return node;
  2096. },readlink:function(node) {
  2097. if (!FS.isLink(node.mode)) {
  2098. throw new FS.ErrnoError(28);
  2099. }
  2100. return node.link;
  2101. }},stream_ops:{read:function(stream, buffer, offset, length, position) {
  2102. var contents = stream.node.contents;
  2103. if (position >= stream.node.usedBytes) return 0;
  2104. var size = Math.min(stream.node.usedBytes - position, length);
  2105. assert(size >= 0);
  2106. if (size > 8 && contents.subarray) { // non-trivial, and typed array
  2107. buffer.set(contents.subarray(position, position + size), offset);
  2108. } else {
  2109. for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
  2110. }
  2111. return size;
  2112. },write:function(stream, buffer, offset, length, position, canOwn) {
  2113. // The data buffer should be a typed array view
  2114. assert(!(buffer instanceof ArrayBuffer));
  2115. if (!length) return 0;
  2116. var node = stream.node;
  2117. node.timestamp = Date.now();
  2118. if (buffer.subarray && (!node.contents || node.contents.subarray)) { // This write is from a typed array to a typed array?
  2119. if (canOwn) {
  2120. assert(position === 0, 'canOwn must imply no weird position inside the file');
  2121. node.contents = buffer.subarray(offset, offset + length);
  2122. node.usedBytes = length;
  2123. return length;
  2124. } else if (node.usedBytes === 0 && position === 0) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data.
  2125. node.contents = buffer.slice(offset, offset + length);
  2126. node.usedBytes = length;
  2127. return length;
  2128. } else if (position + length <= node.usedBytes) { // Writing to an already allocated and used subrange of the file?
  2129. node.contents.set(buffer.subarray(offset, offset + length), position);
  2130. return length;
  2131. }
  2132. }
  2133. // Appending to an existing file and we need to reallocate, or source data did not come as a typed array.
  2134. MEMFS.expandFileStorage(node, position+length);
  2135. if (node.contents.subarray && buffer.subarray) {
  2136. // Use typed array write which is available.
  2137. node.contents.set(buffer.subarray(offset, offset + length), position);
  2138. } else {
  2139. for (var i = 0; i < length; i++) {
  2140. node.contents[position + i] = buffer[offset + i]; // Or fall back to manual write if not.
  2141. }
  2142. }
  2143. node.usedBytes = Math.max(node.usedBytes, position + length);
  2144. return length;
  2145. },llseek:function(stream, offset, whence) {
  2146. var position = offset;
  2147. if (whence === 1) {
  2148. position += stream.position;
  2149. } else if (whence === 2) {
  2150. if (FS.isFile(stream.node.mode)) {
  2151. position += stream.node.usedBytes;
  2152. }
  2153. }
  2154. if (position < 0) {
  2155. throw new FS.ErrnoError(28);
  2156. }
  2157. return position;
  2158. },allocate:function(stream, offset, length) {
  2159. MEMFS.expandFileStorage(stream.node, offset + length);
  2160. stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length);
  2161. },mmap:function(stream, address, length, position, prot, flags) {
  2162. if (address !== 0) {
  2163. // We don't currently support location hints for the address of the mapping
  2164. throw new FS.ErrnoError(28);
  2165. }
  2166. if (!FS.isFile(stream.node.mode)) {
  2167. throw new FS.ErrnoError(43);
  2168. }
  2169. var ptr;
  2170. var allocated;
  2171. var contents = stream.node.contents;
  2172. // Only make a new copy when MAP_PRIVATE is specified.
  2173. if (!(flags & 2) && contents.buffer === buffer) {
  2174. // We can't emulate MAP_SHARED when the file is not backed by the buffer
  2175. // we're mapping to (e.g. the HEAP buffer).
  2176. allocated = false;
  2177. ptr = contents.byteOffset;
  2178. } else {
  2179. // Try to avoid unnecessary slices.
  2180. if (position > 0 || position + length < contents.length) {
  2181. if (contents.subarray) {
  2182. contents = contents.subarray(position, position + length);
  2183. } else {
  2184. contents = Array.prototype.slice.call(contents, position, position + length);
  2185. }
  2186. }
  2187. allocated = true;
  2188. ptr = mmapAlloc(length);
  2189. if (!ptr) {
  2190. throw new FS.ErrnoError(48);
  2191. }
  2192. HEAP8.set(contents, ptr);
  2193. }
  2194. return { ptr: ptr, allocated: allocated };
  2195. },msync:function(stream, buffer, offset, length, mmapFlags) {
  2196. if (!FS.isFile(stream.node.mode)) {
  2197. throw new FS.ErrnoError(43);
  2198. }
  2199. if (mmapFlags & 2) {
  2200. // MAP_PRIVATE calls need not to be synced back to underlying fs
  2201. return 0;
  2202. }
  2203. var bytesWritten = MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);
  2204. // should we check if bytesWritten and length are the same?
  2205. return 0;
  2206. }}};
  2207. /** @param {boolean=} noRunDep */
  2208. function asyncLoad(url, onload, onerror, noRunDep) {
  2209. var dep = !noRunDep ? getUniqueRunDependency('al ' + url) : '';
  2210. readAsync(url, function(arrayBuffer) {
  2211. assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
  2212. onload(new Uint8Array(arrayBuffer));
  2213. if (dep) removeRunDependency(dep);
  2214. }, function(event) {
  2215. if (onerror) {
  2216. onerror();
  2217. } else {
  2218. throw 'Loading data file "' + url + '" failed.';
  2219. }
  2220. });
  2221. if (dep) addRunDependency(dep);
  2222. }
  2223. var ERRNO_MESSAGES = {0:"Success",1:"Arg list too long",2:"Permission denied",3:"Address already in use",4:"Address not available",5:"Address family not supported by protocol family",6:"No more processes",7:"Socket already connected",8:"Bad file number",9:"Trying to read unreadable message",10:"Mount device busy",11:"Operation canceled",12:"No children",13:"Connection aborted",14:"Connection refused",15:"Connection reset by peer",16:"File locking deadlock error",17:"Destination address required",18:"Math arg out of domain of func",19:"Quota exceeded",20:"File exists",21:"Bad address",22:"File too large",23:"Host is unreachable",24:"Identifier removed",25:"Illegal byte sequence",26:"Connection already in progress",27:"Interrupted system call",28:"Invalid argument",29:"I/O error",30:"Socket is already connected",31:"Is a directory",32:"Too many symbolic links",33:"Too many open files",34:"Too many links",35:"Message too long",36:"Multihop attempted",37:"File or path name too long",38:"Network interface is not configured",39:"Connection reset by network",40:"Network is unreachable",41:"Too many open files in system",42:"No buffer space available",43:"No such device",44:"No such file or directory",45:"Exec format error",46:"No record locks available",47:"The link has been severed",48:"Not enough core",49:"No message of desired type",50:"Protocol not available",51:"No space left on device",52:"Function not implemented",53:"Socket is not connected",54:"Not a directory",55:"Directory not empty",56:"State not recoverable",57:"Socket operation on non-socket",59:"Not a typewriter",60:"No such device or address",61:"Value too large for defined data type",62:"Previous owner died",63:"Not super-user",64:"Broken pipe",65:"Protocol error",66:"Unknown protocol",67:"Protocol wrong type for socket",68:"Math result not representable",69:"Read only file system",70:"Illegal seek",71:"No such process",72:"Stale file handle",73:"Connection timed out",74:"Text file busy",75:"Cross-device link",100:"Device not a stream",101:"Bad font file fmt",102:"Invalid slot",103:"Invalid request code",104:"No anode",105:"Block device required",106:"Channel number out of range",107:"Level 3 halted",108:"Level 3 reset",109:"Link number out of range",110:"Protocol driver not attached",111:"No CSI structure available",112:"Level 2 halted",113:"Invalid exchange",114:"Invalid request descriptor",115:"Exchange full",116:"No data (for no delay io)",117:"Timer expired",118:"Out of streams resources",119:"Machine is not on the network",120:"Package not installed",121:"The object is remote",122:"Advertise error",123:"Srmount error",124:"Communication error on send",125:"Cross mount point (not really error)",126:"Given log. name not unique",127:"f.d. invalid for this operation",128:"Remote address changed",129:"Can access a needed shared lib",130:"Accessing a corrupted shared lib",131:".lib section in a.out corrupted",132:"Attempting to link in too many libs",133:"Attempting to exec a shared library",135:"Streams pipe error",136:"Too many users",137:"Socket type not supported",138:"Not supported",139:"Protocol family not supported",140:"Can't send after socket shutdown",141:"Too many references",142:"Host is down",148:"No medium (in tape drive)",156:"Level 2 not synchronized"};
  2224. var ERRNO_CODES = {};
  2225. var FS = {root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath:(path, opts = {}) => {
  2226. path = PATH_FS.resolve(FS.cwd(), path);
  2227. if (!path) return { path: '', node: null };
  2228. var defaults = {
  2229. follow_mount: true,
  2230. recurse_count: 0
  2231. };
  2232. for (var key in defaults) {
  2233. if (opts[key] === undefined) {
  2234. opts[key] = defaults[key];
  2235. }
  2236. }
  2237. if (opts.recurse_count > 8) { // max recursive lookup of 8
  2238. throw new FS.ErrnoError(32);
  2239. }
  2240. // split the path
  2241. var parts = PATH.normalizeArray(path.split('/').filter((p) => !!p), false);
  2242. // start at the root
  2243. var current = FS.root;
  2244. var current_path = '/';
  2245. for (var i = 0; i < parts.length; i++) {
  2246. var islast = (i === parts.length-1);
  2247. if (islast && opts.parent) {
  2248. // stop resolving
  2249. break;
  2250. }
  2251. current = FS.lookupNode(current, parts[i]);
  2252. current_path = PATH.join2(current_path, parts[i]);
  2253. // jump to the mount's root node if this is a mountpoint
  2254. if (FS.isMountpoint(current)) {
  2255. if (!islast || (islast && opts.follow_mount)) {
  2256. current = current.mounted.root;
  2257. }
  2258. }
  2259. // by default, lookupPath will not follow a symlink if it is the final path component.
  2260. // setting opts.follow = true will override this behavior.
  2261. if (!islast || opts.follow) {
  2262. var count = 0;
  2263. while (FS.isLink(current.mode)) {
  2264. var link = FS.readlink(current_path);
  2265. current_path = PATH_FS.resolve(PATH.dirname(current_path), link);
  2266. var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count });
  2267. current = lookup.node;
  2268. if (count++ > 40) { // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
  2269. throw new FS.ErrnoError(32);
  2270. }
  2271. }
  2272. }
  2273. }
  2274. return { path: current_path, node: current };
  2275. },getPath:(node) => {
  2276. var path;
  2277. while (true) {
  2278. if (FS.isRoot(node)) {
  2279. var mount = node.mount.mountpoint;
  2280. if (!path) return mount;
  2281. return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;
  2282. }
  2283. path = path ? node.name + '/' + path : node.name;
  2284. node = node.parent;
  2285. }
  2286. },hashName:(parentid, name) => {
  2287. var hash = 0;
  2288. for (var i = 0; i < name.length; i++) {
  2289. hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
  2290. }
  2291. return ((parentid + hash) >>> 0) % FS.nameTable.length;
  2292. },hashAddNode:(node) => {
  2293. var hash = FS.hashName(node.parent.id, node.name);
  2294. node.name_next = FS.nameTable[hash];
  2295. FS.nameTable[hash] = node;
  2296. },hashRemoveNode:(node) => {
  2297. var hash = FS.hashName(node.parent.id, node.name);
  2298. if (FS.nameTable[hash] === node) {
  2299. FS.nameTable[hash] = node.name_next;
  2300. } else {
  2301. var current = FS.nameTable[hash];
  2302. while (current) {
  2303. if (current.name_next === node) {
  2304. current.name_next = node.name_next;
  2305. break;
  2306. }
  2307. current = current.name_next;
  2308. }
  2309. }
  2310. },lookupNode:(parent, name) => {
  2311. var errCode = FS.mayLookup(parent);
  2312. if (errCode) {
  2313. throw new FS.ErrnoError(errCode, parent);
  2314. }
  2315. var hash = FS.hashName(parent.id, name);
  2316. for (var node = FS.nameTable[hash]; node; node = node.name_next) {
  2317. var nodeName = node.name;
  2318. if (node.parent.id === parent.id && nodeName === name) {
  2319. return node;
  2320. }
  2321. }
  2322. // if we failed to find it in the cache, call into the VFS
  2323. return FS.lookup(parent, name);
  2324. },createNode:(parent, name, mode, rdev) => {
  2325. assert(typeof parent == 'object')
  2326. var node = new FS.FSNode(parent, name, mode, rdev);
  2327. FS.hashAddNode(node);
  2328. return node;
  2329. },destroyNode:(node) => {
  2330. FS.hashRemoveNode(node);
  2331. },isRoot:(node) => {
  2332. return node === node.parent;
  2333. },isMountpoint:(node) => {
  2334. return !!node.mounted;
  2335. },isFile:(mode) => {
  2336. return (mode & 61440) === 32768;
  2337. },isDir:(mode) => {
  2338. return (mode & 61440) === 16384;
  2339. },isLink:(mode) => {
  2340. return (mode & 61440) === 40960;
  2341. },isChrdev:(mode) => {
  2342. return (mode & 61440) === 8192;
  2343. },isBlkdev:(mode) => {
  2344. return (mode & 61440) === 24576;
  2345. },isFIFO:(mode) => {
  2346. return (mode & 61440) === 4096;
  2347. },isSocket:(mode) => {
  2348. return (mode & 49152) === 49152;
  2349. },flagModes:{"r":0,"r+":2,"w":577,"w+":578,"a":1089,"a+":1090},modeStringToFlags:(str) => {
  2350. var flags = FS.flagModes[str];
  2351. if (typeof flags == 'undefined') {
  2352. throw new Error('Unknown file open mode: ' + str);
  2353. }
  2354. return flags;
  2355. },flagsToPermissionString:(flag) => {
  2356. var perms = ['r', 'w', 'rw'][flag & 3];
  2357. if ((flag & 512)) {
  2358. perms += 'w';
  2359. }
  2360. return perms;
  2361. },nodePermissions:(node, perms) => {
  2362. if (FS.ignorePermissions) {
  2363. return 0;
  2364. }
  2365. // return 0 if any user, group or owner bits are set.
  2366. if (perms.includes('r') && !(node.mode & 292)) {
  2367. return 2;
  2368. } else if (perms.includes('w') && !(node.mode & 146)) {
  2369. return 2;
  2370. } else if (perms.includes('x') && !(node.mode & 73)) {
  2371. return 2;
  2372. }
  2373. return 0;
  2374. },mayLookup:(dir) => {
  2375. var errCode = FS.nodePermissions(dir, 'x');
  2376. if (errCode) return errCode;
  2377. if (!dir.node_ops.lookup) return 2;
  2378. return 0;
  2379. },mayCreate:(dir, name) => {
  2380. try {
  2381. var node = FS.lookupNode(dir, name);
  2382. return 20;
  2383. } catch (e) {
  2384. }
  2385. return FS.nodePermissions(dir, 'wx');
  2386. },mayDelete:(dir, name, isdir) => {
  2387. var node;
  2388. try {
  2389. node = FS.lookupNode(dir, name);
  2390. } catch (e) {
  2391. return e.errno;
  2392. }
  2393. var errCode = FS.nodePermissions(dir, 'wx');
  2394. if (errCode) {
  2395. return errCode;
  2396. }
  2397. if (isdir) {
  2398. if (!FS.isDir(node.mode)) {
  2399. return 54;
  2400. }
  2401. if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
  2402. return 10;
  2403. }
  2404. } else {
  2405. if (FS.isDir(node.mode)) {
  2406. return 31;
  2407. }
  2408. }
  2409. return 0;
  2410. },mayOpen:(node, flags) => {
  2411. if (!node) {
  2412. return 44;
  2413. }
  2414. if (FS.isLink(node.mode)) {
  2415. return 32;
  2416. } else if (FS.isDir(node.mode)) {
  2417. if (FS.flagsToPermissionString(flags) !== 'r' || // opening for write
  2418. (flags & 512)) { // TODO: check for O_SEARCH? (== search for dir only)
  2419. return 31;
  2420. }
  2421. }
  2422. return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
  2423. },MAX_OPEN_FDS:4096,nextfd:(fd_start = 0, fd_end = FS.MAX_OPEN_FDS) => {
  2424. for (var fd = fd_start; fd <= fd_end; fd++) {
  2425. if (!FS.streams[fd]) {
  2426. return fd;
  2427. }
  2428. }
  2429. throw new FS.ErrnoError(33);
  2430. },getStream:(fd) => FS.streams[fd],createStream:(stream, fd_start, fd_end) => {
  2431. if (!FS.FSStream) {
  2432. FS.FSStream = /** @constructor */ function(){};
  2433. FS.FSStream.prototype = {
  2434. object: {
  2435. get: function() { return this.node; },
  2436. set: function(val) { this.node = val; }
  2437. },
  2438. isRead: {
  2439. get: function() { return (this.flags & 2097155) !== 1; }
  2440. },
  2441. isWrite: {
  2442. get: function() { return (this.flags & 2097155) !== 0; }
  2443. },
  2444. isAppend: {
  2445. get: function() { return (this.flags & 1024); }
  2446. }
  2447. };
  2448. }
  2449. // clone it, so we can return an instance of FSStream
  2450. stream = Object.assign(new FS.FSStream(), stream);
  2451. var fd = FS.nextfd(fd_start, fd_end);
  2452. stream.fd = fd;
  2453. FS.streams[fd] = stream;
  2454. return stream;
  2455. },closeStream:(fd) => {
  2456. FS.streams[fd] = null;
  2457. },chrdev_stream_ops:{open:(stream) => {
  2458. var device = FS.getDevice(stream.node.rdev);
  2459. // override node's stream ops with the device's
  2460. stream.stream_ops = device.stream_ops;
  2461. // forward the open call
  2462. if (stream.stream_ops.open) {
  2463. stream.stream_ops.open(stream);
  2464. }
  2465. },llseek:() => {
  2466. throw new FS.ErrnoError(70);
  2467. }},major:(dev) => ((dev) >> 8),minor:(dev) => ((dev) & 0xff),makedev:(ma, mi) => ((ma) << 8 | (mi)),registerDevice:(dev, ops) => {
  2468. FS.devices[dev] = { stream_ops: ops };
  2469. },getDevice:(dev) => FS.devices[dev],getMounts:(mount) => {
  2470. var mounts = [];
  2471. var check = [mount];
  2472. while (check.length) {
  2473. var m = check.pop();
  2474. mounts.push(m);
  2475. check.push.apply(check, m.mounts);
  2476. }
  2477. return mounts;
  2478. },syncfs:(populate, callback) => {
  2479. if (typeof populate == 'function') {
  2480. callback = populate;
  2481. populate = false;
  2482. }
  2483. FS.syncFSRequests++;
  2484. if (FS.syncFSRequests > 1) {
  2485. err('warning: ' + FS.syncFSRequests + ' FS.syncfs operations in flight at once, probably just doing extra work');
  2486. }
  2487. var mounts = FS.getMounts(FS.root.mount);
  2488. var completed = 0;
  2489. function doCallback(errCode) {
  2490. assert(FS.syncFSRequests > 0);
  2491. FS.syncFSRequests--;
  2492. return callback(errCode);
  2493. }
  2494. function done(errCode) {
  2495. if (errCode) {
  2496. if (!done.errored) {
  2497. done.errored = true;
  2498. return doCallback(errCode);
  2499. }
  2500. return;
  2501. }
  2502. if (++completed >= mounts.length) {
  2503. doCallback(null);
  2504. }
  2505. };
  2506. // sync all mounts
  2507. mounts.forEach((mount) => {
  2508. if (!mount.type.syncfs) {
  2509. return done(null);
  2510. }
  2511. mount.type.syncfs(mount, populate, done);
  2512. });
  2513. },mount:(type, opts, mountpoint) => {
  2514. if (typeof type == 'string') {
  2515. // The filesystem was not included, and instead we have an error
  2516. // message stored in the variable.
  2517. throw type;
  2518. }
  2519. var root = mountpoint === '/';
  2520. var pseudo = !mountpoint;
  2521. var node;
  2522. if (root && FS.root) {
  2523. throw new FS.ErrnoError(10);
  2524. } else if (!root && !pseudo) {
  2525. var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
  2526. mountpoint = lookup.path; // use the absolute path
  2527. node = lookup.node;
  2528. if (FS.isMountpoint(node)) {
  2529. throw new FS.ErrnoError(10);
  2530. }
  2531. if (!FS.isDir(node.mode)) {
  2532. throw new FS.ErrnoError(54);
  2533. }
  2534. }
  2535. var mount = {
  2536. type: type,
  2537. opts: opts,
  2538. mountpoint: mountpoint,
  2539. mounts: []
  2540. };
  2541. // create a root node for the fs
  2542. var mountRoot = type.mount(mount);
  2543. mountRoot.mount = mount;
  2544. mount.root = mountRoot;
  2545. if (root) {
  2546. FS.root = mountRoot;
  2547. } else if (node) {
  2548. // set as a mountpoint
  2549. node.mounted = mount;
  2550. // add the new mount to the current mount's children
  2551. if (node.mount) {
  2552. node.mount.mounts.push(mount);
  2553. }
  2554. }
  2555. return mountRoot;
  2556. },unmount:(mountpoint) => {
  2557. var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
  2558. if (!FS.isMountpoint(lookup.node)) {
  2559. throw new FS.ErrnoError(28);
  2560. }
  2561. // destroy the nodes for this mount, and all its child mounts
  2562. var node = lookup.node;
  2563. var mount = node.mounted;
  2564. var mounts = FS.getMounts(mount);
  2565. Object.keys(FS.nameTable).forEach((hash) => {
  2566. var current = FS.nameTable[hash];
  2567. while (current) {
  2568. var next = current.name_next;
  2569. if (mounts.includes(current.mount)) {
  2570. FS.destroyNode(current);
  2571. }
  2572. current = next;
  2573. }
  2574. });
  2575. // no longer a mountpoint
  2576. node.mounted = null;
  2577. // remove this mount from the child mounts
  2578. var idx = node.mount.mounts.indexOf(mount);
  2579. assert(idx !== -1);
  2580. node.mount.mounts.splice(idx, 1);
  2581. },lookup:(parent, name) => {
  2582. return parent.node_ops.lookup(parent, name);
  2583. },mknod:(path, mode, dev) => {
  2584. var lookup = FS.lookupPath(path, { parent: true });
  2585. var parent = lookup.node;
  2586. var name = PATH.basename(path);
  2587. if (!name || name === '.' || name === '..') {
  2588. throw new FS.ErrnoError(28);
  2589. }
  2590. var errCode = FS.mayCreate(parent, name);
  2591. if (errCode) {
  2592. throw new FS.ErrnoError(errCode);
  2593. }
  2594. if (!parent.node_ops.mknod) {
  2595. throw new FS.ErrnoError(63);
  2596. }
  2597. return parent.node_ops.mknod(parent, name, mode, dev);
  2598. },create:(path, mode) => {
  2599. mode = mode !== undefined ? mode : 438 /* 0666 */;
  2600. mode &= 4095;
  2601. mode |= 32768;
  2602. return FS.mknod(path, mode, 0);
  2603. },mkdir:(path, mode) => {
  2604. mode = mode !== undefined ? mode : 511 /* 0777 */;
  2605. mode &= 511 | 512;
  2606. mode |= 16384;
  2607. return FS.mknod(path, mode, 0);
  2608. },mkdirTree:(path, mode) => {
  2609. var dirs = path.split('/');
  2610. var d = '';
  2611. for (var i = 0; i < dirs.length; ++i) {
  2612. if (!dirs[i]) continue;
  2613. d += '/' + dirs[i];
  2614. try {
  2615. FS.mkdir(d, mode);
  2616. } catch(e) {
  2617. if (e.errno != 20) throw e;
  2618. }
  2619. }
  2620. },mkdev:(path, mode, dev) => {
  2621. if (typeof dev == 'undefined') {
  2622. dev = mode;
  2623. mode = 438 /* 0666 */;
  2624. }
  2625. mode |= 8192;
  2626. return FS.mknod(path, mode, dev);
  2627. },symlink:(oldpath, newpath) => {
  2628. if (!PATH_FS.resolve(oldpath)) {
  2629. throw new FS.ErrnoError(44);
  2630. }
  2631. var lookup = FS.lookupPath(newpath, { parent: true });
  2632. var parent = lookup.node;
  2633. if (!parent) {
  2634. throw new FS.ErrnoError(44);
  2635. }
  2636. var newname = PATH.basename(newpath);
  2637. var errCode = FS.mayCreate(parent, newname);
  2638. if (errCode) {
  2639. throw new FS.ErrnoError(errCode);
  2640. }
  2641. if (!parent.node_ops.symlink) {
  2642. throw new FS.ErrnoError(63);
  2643. }
  2644. return parent.node_ops.symlink(parent, newname, oldpath);
  2645. },rename:(old_path, new_path) => {
  2646. var old_dirname = PATH.dirname(old_path);
  2647. var new_dirname = PATH.dirname(new_path);
  2648. var old_name = PATH.basename(old_path);
  2649. var new_name = PATH.basename(new_path);
  2650. // parents must exist
  2651. var lookup, old_dir, new_dir;
  2652. // let the errors from non existant directories percolate up
  2653. lookup = FS.lookupPath(old_path, { parent: true });
  2654. old_dir = lookup.node;
  2655. lookup = FS.lookupPath(new_path, { parent: true });
  2656. new_dir = lookup.node;
  2657. if (!old_dir || !new_dir) throw new FS.ErrnoError(44);
  2658. // need to be part of the same mount
  2659. if (old_dir.mount !== new_dir.mount) {
  2660. throw new FS.ErrnoError(75);
  2661. }
  2662. // source must exist
  2663. var old_node = FS.lookupNode(old_dir, old_name);
  2664. // old path should not be an ancestor of the new path
  2665. var relative = PATH_FS.relative(old_path, new_dirname);
  2666. if (relative.charAt(0) !== '.') {
  2667. throw new FS.ErrnoError(28);
  2668. }
  2669. // new path should not be an ancestor of the old path
  2670. relative = PATH_FS.relative(new_path, old_dirname);
  2671. if (relative.charAt(0) !== '.') {
  2672. throw new FS.ErrnoError(55);
  2673. }
  2674. // see if the new path already exists
  2675. var new_node;
  2676. try {
  2677. new_node = FS.lookupNode(new_dir, new_name);
  2678. } catch (e) {
  2679. // not fatal
  2680. }
  2681. // early out if nothing needs to change
  2682. if (old_node === new_node) {
  2683. return;
  2684. }
  2685. // we'll need to delete the old entry
  2686. var isdir = FS.isDir(old_node.mode);
  2687. var errCode = FS.mayDelete(old_dir, old_name, isdir);
  2688. if (errCode) {
  2689. throw new FS.ErrnoError(errCode);
  2690. }
  2691. // need delete permissions if we'll be overwriting.
  2692. // need create permissions if new doesn't already exist.
  2693. errCode = new_node ?
  2694. FS.mayDelete(new_dir, new_name, isdir) :
  2695. FS.mayCreate(new_dir, new_name);
  2696. if (errCode) {
  2697. throw new FS.ErrnoError(errCode);
  2698. }
  2699. if (!old_dir.node_ops.rename) {
  2700. throw new FS.ErrnoError(63);
  2701. }
  2702. if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
  2703. throw new FS.ErrnoError(10);
  2704. }
  2705. // if we are going to change the parent, check write permissions
  2706. if (new_dir !== old_dir) {
  2707. errCode = FS.nodePermissions(old_dir, 'w');
  2708. if (errCode) {
  2709. throw new FS.ErrnoError(errCode);
  2710. }
  2711. }
  2712. // remove the node from the lookup hash
  2713. FS.hashRemoveNode(old_node);
  2714. // do the underlying fs rename
  2715. try {
  2716. old_dir.node_ops.rename(old_node, new_dir, new_name);
  2717. } catch (e) {
  2718. throw e;
  2719. } finally {
  2720. // add the node back to the hash (in case node_ops.rename
  2721. // changed its name)
  2722. FS.hashAddNode(old_node);
  2723. }
  2724. },rmdir:(path) => {
  2725. var lookup = FS.lookupPath(path, { parent: true });
  2726. var parent = lookup.node;
  2727. var name = PATH.basename(path);
  2728. var node = FS.lookupNode(parent, name);
  2729. var errCode = FS.mayDelete(parent, name, true);
  2730. if (errCode) {
  2731. throw new FS.ErrnoError(errCode);
  2732. }
  2733. if (!parent.node_ops.rmdir) {
  2734. throw new FS.ErrnoError(63);
  2735. }
  2736. if (FS.isMountpoint(node)) {
  2737. throw new FS.ErrnoError(10);
  2738. }
  2739. parent.node_ops.rmdir(parent, name);
  2740. FS.destroyNode(node);
  2741. },readdir:(path) => {
  2742. var lookup = FS.lookupPath(path, { follow: true });
  2743. var node = lookup.node;
  2744. if (!node.node_ops.readdir) {
  2745. throw new FS.ErrnoError(54);
  2746. }
  2747. return node.node_ops.readdir(node);
  2748. },unlink:(path) => {
  2749. var lookup = FS.lookupPath(path, { parent: true });
  2750. var parent = lookup.node;
  2751. if (!parent) {
  2752. throw new FS.ErrnoError(44);
  2753. }
  2754. var name = PATH.basename(path);
  2755. var node = FS.lookupNode(parent, name);
  2756. var errCode = FS.mayDelete(parent, name, false);
  2757. if (errCode) {
  2758. // According to POSIX, we should map EISDIR to EPERM, but
  2759. // we instead do what Linux does (and we must, as we use
  2760. // the musl linux libc).
  2761. throw new FS.ErrnoError(errCode);
  2762. }
  2763. if (!parent.node_ops.unlink) {
  2764. throw new FS.ErrnoError(63);
  2765. }
  2766. if (FS.isMountpoint(node)) {
  2767. throw new FS.ErrnoError(10);
  2768. }
  2769. parent.node_ops.unlink(parent, name);
  2770. FS.destroyNode(node);
  2771. },readlink:(path) => {
  2772. var lookup = FS.lookupPath(path);
  2773. var link = lookup.node;
  2774. if (!link) {
  2775. throw new FS.ErrnoError(44);
  2776. }
  2777. if (!link.node_ops.readlink) {
  2778. throw new FS.ErrnoError(28);
  2779. }
  2780. return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link));
  2781. },stat:(path, dontFollow) => {
  2782. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  2783. var node = lookup.node;
  2784. if (!node) {
  2785. throw new FS.ErrnoError(44);
  2786. }
  2787. if (!node.node_ops.getattr) {
  2788. throw new FS.ErrnoError(63);
  2789. }
  2790. return node.node_ops.getattr(node);
  2791. },lstat:(path) => {
  2792. return FS.stat(path, true);
  2793. },chmod:(path, mode, dontFollow) => {
  2794. var node;
  2795. if (typeof path == 'string') {
  2796. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  2797. node = lookup.node;
  2798. } else {
  2799. node = path;
  2800. }
  2801. if (!node.node_ops.setattr) {
  2802. throw new FS.ErrnoError(63);
  2803. }
  2804. node.node_ops.setattr(node, {
  2805. mode: (mode & 4095) | (node.mode & ~4095),
  2806. timestamp: Date.now()
  2807. });
  2808. },lchmod:(path, mode) => {
  2809. FS.chmod(path, mode, true);
  2810. },fchmod:(fd, mode) => {
  2811. var stream = FS.getStream(fd);
  2812. if (!stream) {
  2813. throw new FS.ErrnoError(8);
  2814. }
  2815. FS.chmod(stream.node, mode);
  2816. },chown:(path, uid, gid, dontFollow) => {
  2817. var node;
  2818. if (typeof path == 'string') {
  2819. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  2820. node = lookup.node;
  2821. } else {
  2822. node = path;
  2823. }
  2824. if (!node.node_ops.setattr) {
  2825. throw new FS.ErrnoError(63);
  2826. }
  2827. node.node_ops.setattr(node, {
  2828. timestamp: Date.now()
  2829. // we ignore the uid / gid for now
  2830. });
  2831. },lchown:(path, uid, gid) => {
  2832. FS.chown(path, uid, gid, true);
  2833. },fchown:(fd, uid, gid) => {
  2834. var stream = FS.getStream(fd);
  2835. if (!stream) {
  2836. throw new FS.ErrnoError(8);
  2837. }
  2838. FS.chown(stream.node, uid, gid);
  2839. },truncate:(path, len) => {
  2840. if (len < 0) {
  2841. throw new FS.ErrnoError(28);
  2842. }
  2843. var node;
  2844. if (typeof path == 'string') {
  2845. var lookup = FS.lookupPath(path, { follow: true });
  2846. node = lookup.node;
  2847. } else {
  2848. node = path;
  2849. }
  2850. if (!node.node_ops.setattr) {
  2851. throw new FS.ErrnoError(63);
  2852. }
  2853. if (FS.isDir(node.mode)) {
  2854. throw new FS.ErrnoError(31);
  2855. }
  2856. if (!FS.isFile(node.mode)) {
  2857. throw new FS.ErrnoError(28);
  2858. }
  2859. var errCode = FS.nodePermissions(node, 'w');
  2860. if (errCode) {
  2861. throw new FS.ErrnoError(errCode);
  2862. }
  2863. node.node_ops.setattr(node, {
  2864. size: len,
  2865. timestamp: Date.now()
  2866. });
  2867. },ftruncate:(fd, len) => {
  2868. var stream = FS.getStream(fd);
  2869. if (!stream) {
  2870. throw new FS.ErrnoError(8);
  2871. }
  2872. if ((stream.flags & 2097155) === 0) {
  2873. throw new FS.ErrnoError(28);
  2874. }
  2875. FS.truncate(stream.node, len);
  2876. },utime:(path, atime, mtime) => {
  2877. var lookup = FS.lookupPath(path, { follow: true });
  2878. var node = lookup.node;
  2879. node.node_ops.setattr(node, {
  2880. timestamp: Math.max(atime, mtime)
  2881. });
  2882. },open:(path, flags, mode, fd_start, fd_end) => {
  2883. if (path === "") {
  2884. throw new FS.ErrnoError(44);
  2885. }
  2886. flags = typeof flags == 'string' ? FS.modeStringToFlags(flags) : flags;
  2887. mode = typeof mode == 'undefined' ? 438 /* 0666 */ : mode;
  2888. if ((flags & 64)) {
  2889. mode = (mode & 4095) | 32768;
  2890. } else {
  2891. mode = 0;
  2892. }
  2893. var node;
  2894. if (typeof path == 'object') {
  2895. node = path;
  2896. } else {
  2897. path = PATH.normalize(path);
  2898. try {
  2899. var lookup = FS.lookupPath(path, {
  2900. follow: !(flags & 131072)
  2901. });
  2902. node = lookup.node;
  2903. } catch (e) {
  2904. // ignore
  2905. }
  2906. }
  2907. // perhaps we need to create the node
  2908. var created = false;
  2909. if ((flags & 64)) {
  2910. if (node) {
  2911. // if O_CREAT and O_EXCL are set, error out if the node already exists
  2912. if ((flags & 128)) {
  2913. throw new FS.ErrnoError(20);
  2914. }
  2915. } else {
  2916. // node doesn't exist, try to create it
  2917. node = FS.mknod(path, mode, 0);
  2918. created = true;
  2919. }
  2920. }
  2921. if (!node) {
  2922. throw new FS.ErrnoError(44);
  2923. }
  2924. // can't truncate a device
  2925. if (FS.isChrdev(node.mode)) {
  2926. flags &= ~512;
  2927. }
  2928. // if asked only for a directory, then this must be one
  2929. if ((flags & 65536) && !FS.isDir(node.mode)) {
  2930. throw new FS.ErrnoError(54);
  2931. }
  2932. // check permissions, if this is not a file we just created now (it is ok to
  2933. // create and write to a file with read-only permissions; it is read-only
  2934. // for later use)
  2935. if (!created) {
  2936. var errCode = FS.mayOpen(node, flags);
  2937. if (errCode) {
  2938. throw new FS.ErrnoError(errCode);
  2939. }
  2940. }
  2941. // do truncation if necessary
  2942. if ((flags & 512)) {
  2943. FS.truncate(node, 0);
  2944. }
  2945. // we've already handled these, don't pass down to the underlying vfs
  2946. flags &= ~(128 | 512 | 131072);
  2947. // register the stream with the filesystem
  2948. var stream = FS.createStream({
  2949. node: node,
  2950. path: FS.getPath(node), // we want the absolute path to the node
  2951. flags: flags,
  2952. seekable: true,
  2953. position: 0,
  2954. stream_ops: node.stream_ops,
  2955. // used by the file family libc calls (fopen, fwrite, ferror, etc.)
  2956. ungotten: [],
  2957. error: false
  2958. }, fd_start, fd_end);
  2959. // call the new stream's open function
  2960. if (stream.stream_ops.open) {
  2961. stream.stream_ops.open(stream);
  2962. }
  2963. if (Module['logReadFiles'] && !(flags & 1)) {
  2964. if (!FS.readFiles) FS.readFiles = {};
  2965. if (!(path in FS.readFiles)) {
  2966. FS.readFiles[path] = 1;
  2967. }
  2968. }
  2969. return stream;
  2970. },close:(stream) => {
  2971. if (FS.isClosed(stream)) {
  2972. throw new FS.ErrnoError(8);
  2973. }
  2974. if (stream.getdents) stream.getdents = null; // free readdir state
  2975. try {
  2976. if (stream.stream_ops.close) {
  2977. stream.stream_ops.close(stream);
  2978. }
  2979. } catch (e) {
  2980. throw e;
  2981. } finally {
  2982. FS.closeStream(stream.fd);
  2983. }
  2984. stream.fd = null;
  2985. },isClosed:(stream) => {
  2986. return stream.fd === null;
  2987. },llseek:(stream, offset, whence) => {
  2988. if (FS.isClosed(stream)) {
  2989. throw new FS.ErrnoError(8);
  2990. }
  2991. if (!stream.seekable || !stream.stream_ops.llseek) {
  2992. throw new FS.ErrnoError(70);
  2993. }
  2994. if (whence != 0 && whence != 1 && whence != 2) {
  2995. throw new FS.ErrnoError(28);
  2996. }
  2997. stream.position = stream.stream_ops.llseek(stream, offset, whence);
  2998. stream.ungotten = [];
  2999. return stream.position;
  3000. },read:(stream, buffer, offset, length, position) => {
  3001. if (length < 0 || position < 0) {
  3002. throw new FS.ErrnoError(28);
  3003. }
  3004. if (FS.isClosed(stream)) {
  3005. throw new FS.ErrnoError(8);
  3006. }
  3007. if ((stream.flags & 2097155) === 1) {
  3008. throw new FS.ErrnoError(8);
  3009. }
  3010. if (FS.isDir(stream.node.mode)) {
  3011. throw new FS.ErrnoError(31);
  3012. }
  3013. if (!stream.stream_ops.read) {
  3014. throw new FS.ErrnoError(28);
  3015. }
  3016. var seeking = typeof position != 'undefined';
  3017. if (!seeking) {
  3018. position = stream.position;
  3019. } else if (!stream.seekable) {
  3020. throw new FS.ErrnoError(70);
  3021. }
  3022. var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
  3023. if (!seeking) stream.position += bytesRead;
  3024. return bytesRead;
  3025. },write:(stream, buffer, offset, length, position, canOwn) => {
  3026. if (length < 0 || position < 0) {
  3027. throw new FS.ErrnoError(28);
  3028. }
  3029. if (FS.isClosed(stream)) {
  3030. throw new FS.ErrnoError(8);
  3031. }
  3032. if ((stream.flags & 2097155) === 0) {
  3033. throw new FS.ErrnoError(8);
  3034. }
  3035. if (FS.isDir(stream.node.mode)) {
  3036. throw new FS.ErrnoError(31);
  3037. }
  3038. if (!stream.stream_ops.write) {
  3039. throw new FS.ErrnoError(28);
  3040. }
  3041. if (stream.seekable && stream.flags & 1024) {
  3042. // seek to the end before writing in append mode
  3043. FS.llseek(stream, 0, 2);
  3044. }
  3045. var seeking = typeof position != 'undefined';
  3046. if (!seeking) {
  3047. position = stream.position;
  3048. } else if (!stream.seekable) {
  3049. throw new FS.ErrnoError(70);
  3050. }
  3051. var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
  3052. if (!seeking) stream.position += bytesWritten;
  3053. return bytesWritten;
  3054. },allocate:(stream, offset, length) => {
  3055. if (FS.isClosed(stream)) {
  3056. throw new FS.ErrnoError(8);
  3057. }
  3058. if (offset < 0 || length <= 0) {
  3059. throw new FS.ErrnoError(28);
  3060. }
  3061. if ((stream.flags & 2097155) === 0) {
  3062. throw new FS.ErrnoError(8);
  3063. }
  3064. if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) {
  3065. throw new FS.ErrnoError(43);
  3066. }
  3067. if (!stream.stream_ops.allocate) {
  3068. throw new FS.ErrnoError(138);
  3069. }
  3070. stream.stream_ops.allocate(stream, offset, length);
  3071. },mmap:(stream, address, length, position, prot, flags) => {
  3072. // User requests writing to file (prot & PROT_WRITE != 0).
  3073. // Checking if we have permissions to write to the file unless
  3074. // MAP_PRIVATE flag is set. According to POSIX spec it is possible
  3075. // to write to file opened in read-only mode with MAP_PRIVATE flag,
  3076. // as all modifications will be visible only in the memory of
  3077. // the current process.
  3078. if ((prot & 2) !== 0
  3079. && (flags & 2) === 0
  3080. && (stream.flags & 2097155) !== 2) {
  3081. throw new FS.ErrnoError(2);
  3082. }
  3083. if ((stream.flags & 2097155) === 1) {
  3084. throw new FS.ErrnoError(2);
  3085. }
  3086. if (!stream.stream_ops.mmap) {
  3087. throw new FS.ErrnoError(43);
  3088. }
  3089. return stream.stream_ops.mmap(stream, address, length, position, prot, flags);
  3090. },msync:(stream, buffer, offset, length, mmapFlags) => {
  3091. if (!stream || !stream.stream_ops.msync) {
  3092. return 0;
  3093. }
  3094. return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags);
  3095. },munmap:(stream) => 0,ioctl:(stream, cmd, arg) => {
  3096. if (!stream.stream_ops.ioctl) {
  3097. throw new FS.ErrnoError(59);
  3098. }
  3099. return stream.stream_ops.ioctl(stream, cmd, arg);
  3100. },readFile:(path, opts = {}) => {
  3101. opts.flags = opts.flags || 0;
  3102. opts.encoding = opts.encoding || 'binary';
  3103. if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
  3104. throw new Error('Invalid encoding type "' + opts.encoding + '"');
  3105. }
  3106. var ret;
  3107. var stream = FS.open(path, opts.flags);
  3108. var stat = FS.stat(path);
  3109. var length = stat.size;
  3110. var buf = new Uint8Array(length);
  3111. FS.read(stream, buf, 0, length, 0);
  3112. if (opts.encoding === 'utf8') {
  3113. ret = UTF8ArrayToString(buf, 0);
  3114. } else if (opts.encoding === 'binary') {
  3115. ret = buf;
  3116. }
  3117. FS.close(stream);
  3118. return ret;
  3119. },writeFile:(path, data, opts = {}) => {
  3120. opts.flags = opts.flags || 577;
  3121. var stream = FS.open(path, opts.flags, opts.mode);
  3122. if (typeof data == 'string') {
  3123. var buf = new Uint8Array(lengthBytesUTF8(data)+1);
  3124. var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length);
  3125. FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn);
  3126. } else if (ArrayBuffer.isView(data)) {
  3127. FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
  3128. } else {
  3129. throw new Error('Unsupported data type');
  3130. }
  3131. FS.close(stream);
  3132. },cwd:() => FS.currentPath,chdir:(path) => {
  3133. var lookup = FS.lookupPath(path, { follow: true });
  3134. if (lookup.node === null) {
  3135. throw new FS.ErrnoError(44);
  3136. }
  3137. if (!FS.isDir(lookup.node.mode)) {
  3138. throw new FS.ErrnoError(54);
  3139. }
  3140. var errCode = FS.nodePermissions(lookup.node, 'x');
  3141. if (errCode) {
  3142. throw new FS.ErrnoError(errCode);
  3143. }
  3144. FS.currentPath = lookup.path;
  3145. },createDefaultDirectories:() => {
  3146. FS.mkdir('/tmp');
  3147. FS.mkdir('/home');
  3148. FS.mkdir('/home/web_user');
  3149. },createDefaultDevices:() => {
  3150. // create /dev
  3151. FS.mkdir('/dev');
  3152. // setup /dev/null
  3153. FS.registerDevice(FS.makedev(1, 3), {
  3154. read: () => 0,
  3155. write: (stream, buffer, offset, length, pos) => length,
  3156. });
  3157. FS.mkdev('/dev/null', FS.makedev(1, 3));
  3158. // setup /dev/tty and /dev/tty1
  3159. // stderr needs to print output using err() rather than out()
  3160. // so we register a second tty just for it.
  3161. TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
  3162. TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
  3163. FS.mkdev('/dev/tty', FS.makedev(5, 0));
  3164. FS.mkdev('/dev/tty1', FS.makedev(6, 0));
  3165. // setup /dev/[u]random
  3166. var random_device = getRandomDevice();
  3167. FS.createDevice('/dev', 'random', random_device);
  3168. FS.createDevice('/dev', 'urandom', random_device);
  3169. // we're not going to emulate the actual shm device,
  3170. // just create the tmp dirs that reside in it commonly
  3171. FS.mkdir('/dev/shm');
  3172. FS.mkdir('/dev/shm/tmp');
  3173. },createSpecialDirectories:() => {
  3174. // create /proc/self/fd which allows /proc/self/fd/6 => readlink gives the
  3175. // name of the stream for fd 6 (see test_unistd_ttyname)
  3176. FS.mkdir('/proc');
  3177. var proc_self = FS.mkdir('/proc/self');
  3178. FS.mkdir('/proc/self/fd');
  3179. FS.mount({
  3180. mount: () => {
  3181. var node = FS.createNode(proc_self, 'fd', 16384 | 511 /* 0777 */, 73);
  3182. node.node_ops = {
  3183. lookup: (parent, name) => {
  3184. var fd = +name;
  3185. var stream = FS.getStream(fd);
  3186. if (!stream) throw new FS.ErrnoError(8);
  3187. var ret = {
  3188. parent: null,
  3189. mount: { mountpoint: 'fake' },
  3190. node_ops: { readlink: () => stream.path },
  3191. };
  3192. ret.parent = ret; // make it look like a simple root node
  3193. return ret;
  3194. }
  3195. };
  3196. return node;
  3197. }
  3198. }, {}, '/proc/self/fd');
  3199. },createStandardStreams:() => {
  3200. // TODO deprecate the old functionality of a single
  3201. // input / output callback and that utilizes FS.createDevice
  3202. // and instead require a unique set of stream ops
  3203. // by default, we symlink the standard streams to the
  3204. // default tty devices. however, if the standard streams
  3205. // have been overwritten we create a unique device for
  3206. // them instead.
  3207. if (Module['stdin']) {
  3208. FS.createDevice('/dev', 'stdin', Module['stdin']);
  3209. } else {
  3210. FS.symlink('/dev/tty', '/dev/stdin');
  3211. }
  3212. if (Module['stdout']) {
  3213. FS.createDevice('/dev', 'stdout', null, Module['stdout']);
  3214. } else {
  3215. FS.symlink('/dev/tty', '/dev/stdout');
  3216. }
  3217. if (Module['stderr']) {
  3218. FS.createDevice('/dev', 'stderr', null, Module['stderr']);
  3219. } else {
  3220. FS.symlink('/dev/tty1', '/dev/stderr');
  3221. }
  3222. // open default streams for the stdin, stdout and stderr devices
  3223. var stdin = FS.open('/dev/stdin', 0);
  3224. var stdout = FS.open('/dev/stdout', 1);
  3225. var stderr = FS.open('/dev/stderr', 1);
  3226. assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');
  3227. assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');
  3228. assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');
  3229. },ensureErrnoError:() => {
  3230. if (FS.ErrnoError) return;
  3231. FS.ErrnoError = /** @this{Object} */ function ErrnoError(errno, node) {
  3232. this.node = node;
  3233. this.setErrno = /** @this{Object} */ function(errno) {
  3234. this.errno = errno;
  3235. for (var key in ERRNO_CODES) {
  3236. if (ERRNO_CODES[key] === errno) {
  3237. this.code = key;
  3238. break;
  3239. }
  3240. }
  3241. };
  3242. this.setErrno(errno);
  3243. this.message = ERRNO_MESSAGES[errno];
  3244. // Try to get a maximally helpful stack trace. On Node.js, getting Error.stack
  3245. // now ensures it shows what we want.
  3246. if (this.stack) {
  3247. // Define the stack property for Node.js 4, which otherwise errors on the next line.
  3248. Object.defineProperty(this, "stack", { value: (new Error).stack, writable: true });
  3249. this.stack = demangleAll(this.stack);
  3250. }
  3251. };
  3252. FS.ErrnoError.prototype = new Error();
  3253. FS.ErrnoError.prototype.constructor = FS.ErrnoError;
  3254. // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
  3255. [44].forEach((code) => {
  3256. FS.genericErrors[code] = new FS.ErrnoError(code);
  3257. FS.genericErrors[code].stack = '<generic error, no stack>';
  3258. });
  3259. },staticInit:() => {
  3260. FS.ensureErrnoError();
  3261. FS.nameTable = new Array(4096);
  3262. FS.mount(MEMFS, {}, '/');
  3263. FS.createDefaultDirectories();
  3264. FS.createDefaultDevices();
  3265. FS.createSpecialDirectories();
  3266. FS.filesystems = {
  3267. 'MEMFS': MEMFS,
  3268. };
  3269. },init:(input, output, error) => {
  3270. assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
  3271. FS.init.initialized = true;
  3272. FS.ensureErrnoError();
  3273. // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
  3274. Module['stdin'] = input || Module['stdin'];
  3275. Module['stdout'] = output || Module['stdout'];
  3276. Module['stderr'] = error || Module['stderr'];
  3277. FS.createStandardStreams();
  3278. },quit:() => {
  3279. FS.init.initialized = false;
  3280. // Call musl-internal function to close all stdio streams, so nothing is
  3281. // left in internal buffers.
  3282. ___stdio_exit();
  3283. // close all of our streams
  3284. for (var i = 0; i < FS.streams.length; i++) {
  3285. var stream = FS.streams[i];
  3286. if (!stream) {
  3287. continue;
  3288. }
  3289. FS.close(stream);
  3290. }
  3291. },getMode:(canRead, canWrite) => {
  3292. var mode = 0;
  3293. if (canRead) mode |= 292 | 73;
  3294. if (canWrite) mode |= 146;
  3295. return mode;
  3296. },findObject:(path, dontResolveLastLink) => {
  3297. var ret = FS.analyzePath(path, dontResolveLastLink);
  3298. if (ret.exists) {
  3299. return ret.object;
  3300. } else {
  3301. return null;
  3302. }
  3303. },analyzePath:(path, dontResolveLastLink) => {
  3304. // operate from within the context of the symlink's target
  3305. try {
  3306. var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
  3307. path = lookup.path;
  3308. } catch (e) {
  3309. }
  3310. var ret = {
  3311. isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
  3312. parentExists: false, parentPath: null, parentObject: null
  3313. };
  3314. try {
  3315. var lookup = FS.lookupPath(path, { parent: true });
  3316. ret.parentExists = true;
  3317. ret.parentPath = lookup.path;
  3318. ret.parentObject = lookup.node;
  3319. ret.name = PATH.basename(path);
  3320. lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
  3321. ret.exists = true;
  3322. ret.path = lookup.path;
  3323. ret.object = lookup.node;
  3324. ret.name = lookup.node.name;
  3325. ret.isRoot = lookup.path === '/';
  3326. } catch (e) {
  3327. ret.error = e.errno;
  3328. };
  3329. return ret;
  3330. },createPath:(parent, path, canRead, canWrite) => {
  3331. parent = typeof parent == 'string' ? parent : FS.getPath(parent);
  3332. var parts = path.split('/').reverse();
  3333. while (parts.length) {
  3334. var part = parts.pop();
  3335. if (!part) continue;
  3336. var current = PATH.join2(parent, part);
  3337. try {
  3338. FS.mkdir(current);
  3339. } catch (e) {
  3340. // ignore EEXIST
  3341. }
  3342. parent = current;
  3343. }
  3344. return current;
  3345. },createFile:(parent, name, properties, canRead, canWrite) => {
  3346. var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name);
  3347. var mode = FS.getMode(canRead, canWrite);
  3348. return FS.create(path, mode);
  3349. },createDataFile:(parent, name, data, canRead, canWrite, canOwn) => {
  3350. var path = name;
  3351. if (parent) {
  3352. parent = typeof parent == 'string' ? parent : FS.getPath(parent);
  3353. path = name ? PATH.join2(parent, name) : parent;
  3354. }
  3355. var mode = FS.getMode(canRead, canWrite);
  3356. var node = FS.create(path, mode);
  3357. if (data) {
  3358. if (typeof data == 'string') {
  3359. var arr = new Array(data.length);
  3360. for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
  3361. data = arr;
  3362. }
  3363. // make sure we can write to the file
  3364. FS.chmod(node, mode | 146);
  3365. var stream = FS.open(node, 577);
  3366. FS.write(stream, data, 0, data.length, 0, canOwn);
  3367. FS.close(stream);
  3368. FS.chmod(node, mode);
  3369. }
  3370. return node;
  3371. },createDevice:(parent, name, input, output) => {
  3372. var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name);
  3373. var mode = FS.getMode(!!input, !!output);
  3374. if (!FS.createDevice.major) FS.createDevice.major = 64;
  3375. var dev = FS.makedev(FS.createDevice.major++, 0);
  3376. // Create a fake device that a set of stream ops to emulate
  3377. // the old behavior.
  3378. FS.registerDevice(dev, {
  3379. open: (stream) => {
  3380. stream.seekable = false;
  3381. },
  3382. close: (stream) => {
  3383. // flush any pending line data
  3384. if (output && output.buffer && output.buffer.length) {
  3385. output(10);
  3386. }
  3387. },
  3388. read: (stream, buffer, offset, length, pos /* ignored */) => {
  3389. var bytesRead = 0;
  3390. for (var i = 0; i < length; i++) {
  3391. var result;
  3392. try {
  3393. result = input();
  3394. } catch (e) {
  3395. throw new FS.ErrnoError(29);
  3396. }
  3397. if (result === undefined && bytesRead === 0) {
  3398. throw new FS.ErrnoError(6);
  3399. }
  3400. if (result === null || result === undefined) break;
  3401. bytesRead++;
  3402. buffer[offset+i] = result;
  3403. }
  3404. if (bytesRead) {
  3405. stream.node.timestamp = Date.now();
  3406. }
  3407. return bytesRead;
  3408. },
  3409. write: (stream, buffer, offset, length, pos) => {
  3410. for (var i = 0; i < length; i++) {
  3411. try {
  3412. output(buffer[offset+i]);
  3413. } catch (e) {
  3414. throw new FS.ErrnoError(29);
  3415. }
  3416. }
  3417. if (length) {
  3418. stream.node.timestamp = Date.now();
  3419. }
  3420. return i;
  3421. }
  3422. });
  3423. return FS.mkdev(path, mode, dev);
  3424. },forceLoadFile:(obj) => {
  3425. if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
  3426. if (typeof XMLHttpRequest != 'undefined') {
  3427. throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
  3428. } else if (read_) {
  3429. // Command-line.
  3430. try {
  3431. // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
  3432. // read() will try to parse UTF8.
  3433. obj.contents = intArrayFromString(read_(obj.url), true);
  3434. obj.usedBytes = obj.contents.length;
  3435. } catch (e) {
  3436. throw new FS.ErrnoError(29);
  3437. }
  3438. } else {
  3439. throw new Error('Cannot load without read() or XMLHttpRequest.');
  3440. }
  3441. },createLazyFile:(parent, name, url, canRead, canWrite) => {
  3442. // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
  3443. /** @constructor */
  3444. function LazyUint8Array() {
  3445. this.lengthKnown = false;
  3446. this.chunks = []; // Loaded chunks. Index is the chunk number
  3447. }
  3448. LazyUint8Array.prototype.get = /** @this{Object} */ function LazyUint8Array_get(idx) {
  3449. if (idx > this.length-1 || idx < 0) {
  3450. return undefined;
  3451. }
  3452. var chunkOffset = idx % this.chunkSize;
  3453. var chunkNum = (idx / this.chunkSize)|0;
  3454. return this.getter(chunkNum)[chunkOffset];
  3455. };
  3456. LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
  3457. this.getter = getter;
  3458. };
  3459. LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
  3460. // Find length
  3461. var xhr = new XMLHttpRequest();
  3462. xhr.open('HEAD', url, false);
  3463. xhr.send(null);
  3464. if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
  3465. var datalength = Number(xhr.getResponseHeader("Content-length"));
  3466. var header;
  3467. var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
  3468. var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip";
  3469. var chunkSize = 1024*1024; // Chunk size in bytes
  3470. if (!hasByteServing) chunkSize = datalength;
  3471. // Function to get a range from the remote URL.
  3472. var doXHR = (from, to) => {
  3473. if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
  3474. if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
  3475. // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
  3476. var xhr = new XMLHttpRequest();
  3477. xhr.open('GET', url, false);
  3478. if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
  3479. // Some hints to the browser that we want binary data.
  3480. xhr.responseType = 'arraybuffer';
  3481. if (xhr.overrideMimeType) {
  3482. xhr.overrideMimeType('text/plain; charset=x-user-defined');
  3483. }
  3484. xhr.send(null);
  3485. if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
  3486. if (xhr.response !== undefined) {
  3487. return new Uint8Array(/** @type{Array<number>} */(xhr.response || []));
  3488. } else {
  3489. return intArrayFromString(xhr.responseText || '', true);
  3490. }
  3491. };
  3492. var lazyArray = this;
  3493. lazyArray.setDataGetter((chunkNum) => {
  3494. var start = chunkNum * chunkSize;
  3495. var end = (chunkNum+1) * chunkSize - 1; // including this byte
  3496. end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
  3497. if (typeof lazyArray.chunks[chunkNum] == 'undefined') {
  3498. lazyArray.chunks[chunkNum] = doXHR(start, end);
  3499. }
  3500. if (typeof lazyArray.chunks[chunkNum] == 'undefined') throw new Error('doXHR failed!');
  3501. return lazyArray.chunks[chunkNum];
  3502. });
  3503. if (usesGzip || !datalength) {
  3504. // if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length
  3505. chunkSize = datalength = 1; // this will force getter(0)/doXHR do download the whole file
  3506. datalength = this.getter(0).length;
  3507. chunkSize = datalength;
  3508. out("LazyFiles on gzip forces download of the whole file when length is accessed");
  3509. }
  3510. this._length = datalength;
  3511. this._chunkSize = chunkSize;
  3512. this.lengthKnown = true;
  3513. };
  3514. if (typeof XMLHttpRequest != 'undefined') {
  3515. if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
  3516. var lazyArray = new LazyUint8Array();
  3517. Object.defineProperties(lazyArray, {
  3518. length: {
  3519. get: /** @this{Object} */ function() {
  3520. if (!this.lengthKnown) {
  3521. this.cacheLength();
  3522. }
  3523. return this._length;
  3524. }
  3525. },
  3526. chunkSize: {
  3527. get: /** @this{Object} */ function() {
  3528. if (!this.lengthKnown) {
  3529. this.cacheLength();
  3530. }
  3531. return this._chunkSize;
  3532. }
  3533. }
  3534. });
  3535. var properties = { isDevice: false, contents: lazyArray };
  3536. } else {
  3537. var properties = { isDevice: false, url: url };
  3538. }
  3539. var node = FS.createFile(parent, name, properties, canRead, canWrite);
  3540. // This is a total hack, but I want to get this lazy file code out of the
  3541. // core of MEMFS. If we want to keep this lazy file concept I feel it should
  3542. // be its own thin LAZYFS proxying calls to MEMFS.
  3543. if (properties.contents) {
  3544. node.contents = properties.contents;
  3545. } else if (properties.url) {
  3546. node.contents = null;
  3547. node.url = properties.url;
  3548. }
  3549. // Add a function that defers querying the file size until it is asked the first time.
  3550. Object.defineProperties(node, {
  3551. usedBytes: {
  3552. get: /** @this {FSNode} */ function() { return this.contents.length; }
  3553. }
  3554. });
  3555. // override each stream op with one that tries to force load the lazy file first
  3556. var stream_ops = {};
  3557. var keys = Object.keys(node.stream_ops);
  3558. keys.forEach((key) => {
  3559. var fn = node.stream_ops[key];
  3560. stream_ops[key] = function forceLoadLazyFile() {
  3561. FS.forceLoadFile(node);
  3562. return fn.apply(null, arguments);
  3563. };
  3564. });
  3565. // use a custom read function
  3566. stream_ops.read = (stream, buffer, offset, length, position) => {
  3567. FS.forceLoadFile(node);
  3568. var contents = stream.node.contents;
  3569. if (position >= contents.length)
  3570. return 0;
  3571. var size = Math.min(contents.length - position, length);
  3572. assert(size >= 0);
  3573. if (contents.slice) { // normal array
  3574. for (var i = 0; i < size; i++) {
  3575. buffer[offset + i] = contents[position + i];
  3576. }
  3577. } else {
  3578. for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
  3579. buffer[offset + i] = contents.get(position + i);
  3580. }
  3581. }
  3582. return size;
  3583. };
  3584. node.stream_ops = stream_ops;
  3585. return node;
  3586. },createPreloadedFile:(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => {
  3587. // TODO we should allow people to just pass in a complete filename instead
  3588. // of parent and name being that we just join them anyways
  3589. var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;
  3590. var dep = getUniqueRunDependency('cp ' + fullname); // might have several active requests for the same fullname
  3591. function processData(byteArray) {
  3592. function finish(byteArray) {
  3593. if (preFinish) preFinish();
  3594. if (!dontCreateFile) {
  3595. FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
  3596. }
  3597. if (onload) onload();
  3598. removeRunDependency(dep);
  3599. }
  3600. if (Browser.handledByPreloadPlugin(byteArray, fullname, finish, () => {
  3601. if (onerror) onerror();
  3602. removeRunDependency(dep);
  3603. })) {
  3604. return;
  3605. }
  3606. finish(byteArray);
  3607. }
  3608. addRunDependency(dep);
  3609. if (typeof url == 'string') {
  3610. asyncLoad(url, (byteArray) => processData(byteArray), onerror);
  3611. } else {
  3612. processData(url);
  3613. }
  3614. },indexedDB:() => {
  3615. return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
  3616. },DB_NAME:() => {
  3617. return 'EM_FS_' + window.location.pathname;
  3618. },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:(paths, onload, onerror) => {
  3619. onload = onload || (() => {});
  3620. onerror = onerror || (() => {});
  3621. var indexedDB = FS.indexedDB();
  3622. try {
  3623. var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
  3624. } catch (e) {
  3625. return onerror(e);
  3626. }
  3627. openRequest.onupgradeneeded = () => {
  3628. out('creating db');
  3629. var db = openRequest.result;
  3630. db.createObjectStore(FS.DB_STORE_NAME);
  3631. };
  3632. openRequest.onsuccess = () => {
  3633. var db = openRequest.result;
  3634. var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');
  3635. var files = transaction.objectStore(FS.DB_STORE_NAME);
  3636. var ok = 0, fail = 0, total = paths.length;
  3637. function finish() {
  3638. if (fail == 0) onload(); else onerror();
  3639. }
  3640. paths.forEach((path) => {
  3641. var putRequest = files.put(FS.analyzePath(path).object.contents, path);
  3642. putRequest.onsuccess = () => { ok++; if (ok + fail == total) finish() };
  3643. putRequest.onerror = () => { fail++; if (ok + fail == total) finish() };
  3644. });
  3645. transaction.onerror = onerror;
  3646. };
  3647. openRequest.onerror = onerror;
  3648. },loadFilesFromDB:(paths, onload, onerror) => {
  3649. onload = onload || (() => {});
  3650. onerror = onerror || (() => {});
  3651. var indexedDB = FS.indexedDB();
  3652. try {
  3653. var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
  3654. } catch (e) {
  3655. return onerror(e);
  3656. }
  3657. openRequest.onupgradeneeded = onerror; // no database to load from
  3658. openRequest.onsuccess = () => {
  3659. var db = openRequest.result;
  3660. try {
  3661. var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');
  3662. } catch(e) {
  3663. onerror(e);
  3664. return;
  3665. }
  3666. var files = transaction.objectStore(FS.DB_STORE_NAME);
  3667. var ok = 0, fail = 0, total = paths.length;
  3668. function finish() {
  3669. if (fail == 0) onload(); else onerror();
  3670. }
  3671. paths.forEach((path) => {
  3672. var getRequest = files.get(path);
  3673. getRequest.onsuccess = () => {
  3674. if (FS.analyzePath(path).exists) {
  3675. FS.unlink(path);
  3676. }
  3677. FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
  3678. ok++;
  3679. if (ok + fail == total) finish();
  3680. };
  3681. getRequest.onerror = () => { fail++; if (ok + fail == total) finish() };
  3682. });
  3683. transaction.onerror = onerror;
  3684. };
  3685. openRequest.onerror = onerror;
  3686. },absolutePath:() => {
  3687. abort('FS.absolutePath has been removed; use PATH_FS.resolve instead');
  3688. },createFolder:() => {
  3689. abort('FS.createFolder has been removed; use FS.mkdir instead');
  3690. },createLink:() => {
  3691. abort('FS.createLink has been removed; use FS.symlink instead');
  3692. },joinPath:() => {
  3693. abort('FS.joinPath has been removed; use PATH.join instead');
  3694. },mmapAlloc:() => {
  3695. abort('FS.mmapAlloc has been replaced by the top level function mmapAlloc');
  3696. },standardizePath:() => {
  3697. abort('FS.standardizePath has been removed; use PATH.normalize instead');
  3698. }};
  3699. var SYSCALLS = {DEFAULT_POLLMASK:5,calculateAt:function(dirfd, path, allowEmpty) {
  3700. if (path[0] === '/') {
  3701. return path;
  3702. }
  3703. // relative path
  3704. var dir;
  3705. if (dirfd === -100) {
  3706. dir = FS.cwd();
  3707. } else {
  3708. var dirstream = FS.getStream(dirfd);
  3709. if (!dirstream) throw new FS.ErrnoError(8);
  3710. dir = dirstream.path;
  3711. }
  3712. if (path.length == 0) {
  3713. if (!allowEmpty) {
  3714. throw new FS.ErrnoError(44);;
  3715. }
  3716. return dir;
  3717. }
  3718. return PATH.join2(dir, path);
  3719. },doStat:function(func, path, buf) {
  3720. try {
  3721. var stat = func(path);
  3722. } catch (e) {
  3723. if (e && e.node && PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))) {
  3724. // an error occurred while trying to look up the path; we should just report ENOTDIR
  3725. return -54;
  3726. }
  3727. throw e;
  3728. }
  3729. HEAP32[((buf)>>2)] = stat.dev;
  3730. HEAP32[(((buf)+(4))>>2)] = 0;
  3731. HEAP32[(((buf)+(8))>>2)] = stat.ino;
  3732. HEAP32[(((buf)+(12))>>2)] = stat.mode;
  3733. HEAP32[(((buf)+(16))>>2)] = stat.nlink;
  3734. HEAP32[(((buf)+(20))>>2)] = stat.uid;
  3735. HEAP32[(((buf)+(24))>>2)] = stat.gid;
  3736. HEAP32[(((buf)+(28))>>2)] = stat.rdev;
  3737. HEAP32[(((buf)+(32))>>2)] = 0;
  3738. (tempI64 = [stat.size>>>0,(tempDouble=stat.size,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(40))>>2)] = tempI64[0],HEAP32[(((buf)+(44))>>2)] = tempI64[1]);
  3739. HEAP32[(((buf)+(48))>>2)] = 4096;
  3740. HEAP32[(((buf)+(52))>>2)] = stat.blocks;
  3741. HEAP32[(((buf)+(56))>>2)] = (stat.atime.getTime() / 1000)|0;
  3742. HEAP32[(((buf)+(60))>>2)] = 0;
  3743. HEAP32[(((buf)+(64))>>2)] = (stat.mtime.getTime() / 1000)|0;
  3744. HEAP32[(((buf)+(68))>>2)] = 0;
  3745. HEAP32[(((buf)+(72))>>2)] = (stat.ctime.getTime() / 1000)|0;
  3746. HEAP32[(((buf)+(76))>>2)] = 0;
  3747. (tempI64 = [stat.ino>>>0,(tempDouble=stat.ino,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(80))>>2)] = tempI64[0],HEAP32[(((buf)+(84))>>2)] = tempI64[1]);
  3748. return 0;
  3749. },doMsync:function(addr, stream, len, flags, offset) {
  3750. var buffer = HEAPU8.slice(addr, addr + len);
  3751. FS.msync(stream, buffer, offset, len, flags);
  3752. },doMkdir:function(path, mode) {
  3753. // remove a trailing slash, if one - /a/b/ has basename of '', but
  3754. // we want to create b in the context of this function
  3755. path = PATH.normalize(path);
  3756. if (path[path.length-1] === '/') path = path.substr(0, path.length-1);
  3757. FS.mkdir(path, mode, 0);
  3758. return 0;
  3759. },doMknod:function(path, mode, dev) {
  3760. // we don't want this in the JS API as it uses mknod to create all nodes.
  3761. switch (mode & 61440) {
  3762. case 32768:
  3763. case 8192:
  3764. case 24576:
  3765. case 4096:
  3766. case 49152:
  3767. break;
  3768. default: return -28;
  3769. }
  3770. FS.mknod(path, mode, dev);
  3771. return 0;
  3772. },doReadlink:function(path, buf, bufsize) {
  3773. if (bufsize <= 0) return -28;
  3774. var ret = FS.readlink(path);
  3775. var len = Math.min(bufsize, lengthBytesUTF8(ret));
  3776. var endChar = HEAP8[buf+len];
  3777. stringToUTF8(ret, buf, bufsize+1);
  3778. // readlink is one of the rare functions that write out a C string, but does never append a null to the output buffer(!)
  3779. // stringToUTF8() always appends a null byte, so restore the character under the null byte after the write.
  3780. HEAP8[buf+len] = endChar;
  3781. return len;
  3782. },doAccess:function(path, amode) {
  3783. if (amode & ~7) {
  3784. // need a valid mode
  3785. return -28;
  3786. }
  3787. var lookup = FS.lookupPath(path, { follow: true });
  3788. var node = lookup.node;
  3789. if (!node) {
  3790. return -44;
  3791. }
  3792. var perms = '';
  3793. if (amode & 4) perms += 'r';
  3794. if (amode & 2) perms += 'w';
  3795. if (amode & 1) perms += 'x';
  3796. if (perms /* otherwise, they've just passed F_OK */ && FS.nodePermissions(node, perms)) {
  3797. return -2;
  3798. }
  3799. return 0;
  3800. },doDup:function(path, flags, suggestFD) {
  3801. var suggest = FS.getStream(suggestFD);
  3802. if (suggest) FS.close(suggest);
  3803. return FS.open(path, flags, 0, suggestFD, suggestFD).fd;
  3804. },doReadv:function(stream, iov, iovcnt, offset) {
  3805. var ret = 0;
  3806. for (var i = 0; i < iovcnt; i++) {
  3807. var ptr = HEAP32[(((iov)+(i*8))>>2)];
  3808. var len = HEAP32[(((iov)+(i*8 + 4))>>2)];
  3809. var curr = FS.read(stream, HEAP8,ptr, len, offset);
  3810. if (curr < 0) return -1;
  3811. ret += curr;
  3812. if (curr < len) break; // nothing more to read
  3813. }
  3814. return ret;
  3815. },doWritev:function(stream, iov, iovcnt, offset) {
  3816. var ret = 0;
  3817. for (var i = 0; i < iovcnt; i++) {
  3818. var ptr = HEAP32[(((iov)+(i*8))>>2)];
  3819. var len = HEAP32[(((iov)+(i*8 + 4))>>2)];
  3820. var curr = FS.write(stream, HEAP8,ptr, len, offset);
  3821. if (curr < 0) return -1;
  3822. ret += curr;
  3823. }
  3824. return ret;
  3825. },varargs:undefined,get:function() {
  3826. assert(SYSCALLS.varargs != undefined);
  3827. SYSCALLS.varargs += 4;
  3828. var ret = HEAP32[(((SYSCALLS.varargs)-(4))>>2)];
  3829. return ret;
  3830. },getStr:function(ptr) {
  3831. var ret = UTF8ToString(ptr);
  3832. return ret;
  3833. },getStreamFromFD:function(fd) {
  3834. var stream = FS.getStream(fd);
  3835. if (!stream) throw new FS.ErrnoError(8);
  3836. return stream;
  3837. },get64:function(low, high) {
  3838. if (low >= 0) assert(high === 0);
  3839. else assert(high === -1);
  3840. return low;
  3841. }};
  3842. function ___syscall_fcntl64(fd, cmd, varargs) {
  3843. SYSCALLS.varargs = varargs;
  3844. try {
  3845. var stream = SYSCALLS.getStreamFromFD(fd);
  3846. switch (cmd) {
  3847. case 0: {
  3848. var arg = SYSCALLS.get();
  3849. if (arg < 0) {
  3850. return -28;
  3851. }
  3852. var newStream;
  3853. newStream = FS.open(stream.path, stream.flags, 0, arg);
  3854. return newStream.fd;
  3855. }
  3856. case 1:
  3857. case 2:
  3858. return 0; // FD_CLOEXEC makes no sense for a single process.
  3859. case 3:
  3860. return stream.flags;
  3861. case 4: {
  3862. var arg = SYSCALLS.get();
  3863. stream.flags |= arg;
  3864. return 0;
  3865. }
  3866. case 5:
  3867. /* case 5: Currently in musl F_GETLK64 has same value as F_GETLK, so omitted to avoid duplicate case blocks. If that changes, uncomment this */ {
  3868. var arg = SYSCALLS.get();
  3869. var offset = 0;
  3870. // We're always unlocked.
  3871. HEAP16[(((arg)+(offset))>>1)] = 2;
  3872. return 0;
  3873. }
  3874. case 6:
  3875. case 7:
  3876. /* case 6: Currently in musl F_SETLK64 has same value as F_SETLK, so omitted to avoid duplicate case blocks. If that changes, uncomment this */
  3877. /* case 7: Currently in musl F_SETLKW64 has same value as F_SETLKW, so omitted to avoid duplicate case blocks. If that changes, uncomment this */
  3878. return 0; // Pretend that the locking is successful.
  3879. case 16:
  3880. case 8:
  3881. return -28; // These are for sockets. We don't have them fully implemented yet.
  3882. case 9:
  3883. // musl trusts getown return values, due to a bug where they must be, as they overlap with errors. just return -1 here, so fnctl() returns that, and we set errno ourselves.
  3884. setErrNo(28);
  3885. return -1;
  3886. default: {
  3887. return -28;
  3888. }
  3889. }
  3890. } catch (e) {
  3891. if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
  3892. return -e.errno;
  3893. }
  3894. }
  3895. function ___syscall_ioctl(fd, op, varargs) {
  3896. SYSCALLS.varargs = varargs;
  3897. try {
  3898. var stream = SYSCALLS.getStreamFromFD(fd);
  3899. switch (op) {
  3900. case 21509:
  3901. case 21505: {
  3902. if (!stream.tty) return -59;
  3903. return 0;
  3904. }
  3905. case 21510:
  3906. case 21511:
  3907. case 21512:
  3908. case 21506:
  3909. case 21507:
  3910. case 21508: {
  3911. if (!stream.tty) return -59;
  3912. return 0; // no-op, not actually adjusting terminal settings
  3913. }
  3914. case 21519: {
  3915. if (!stream.tty) return -59;
  3916. var argp = SYSCALLS.get();
  3917. HEAP32[((argp)>>2)] = 0;
  3918. return 0;
  3919. }
  3920. case 21520: {
  3921. if (!stream.tty) return -59;
  3922. return -28; // not supported
  3923. }
  3924. case 21531: {
  3925. var argp = SYSCALLS.get();
  3926. return FS.ioctl(stream, op, argp);
  3927. }
  3928. case 21523: {
  3929. // TODO: in theory we should write to the winsize struct that gets
  3930. // passed in, but for now musl doesn't read anything on it
  3931. if (!stream.tty) return -59;
  3932. return 0;
  3933. }
  3934. case 21524: {
  3935. // TODO: technically, this ioctl call should change the window size.
  3936. // but, since emscripten doesn't have any concept of a terminal window
  3937. // yet, we'll just silently throw it away as we do TIOCGWINSZ
  3938. if (!stream.tty) return -59;
  3939. return 0;
  3940. }
  3941. default: abort('bad ioctl syscall ' + op);
  3942. }
  3943. } catch (e) {
  3944. if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
  3945. return -e.errno;
  3946. }
  3947. }
  3948. function ___syscall_open(path, flags, varargs) {
  3949. SYSCALLS.varargs = varargs;
  3950. try {
  3951. var pathname = SYSCALLS.getStr(path);
  3952. var mode = varargs ? SYSCALLS.get() : 0;
  3953. var stream = FS.open(pathname, flags, mode);
  3954. return stream.fd;
  3955. } catch (e) {
  3956. if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
  3957. return -e.errno;
  3958. }
  3959. }
  3960. function _abort() {
  3961. abort('native code called abort()');
  3962. }
  3963. function _emscripten_memcpy_big(dest, src, num) {
  3964. HEAPU8.copyWithin(dest, src, src + num);
  3965. }
  3966. function _emscripten_get_heap_max() {
  3967. return HEAPU8.length;
  3968. }
  3969. function abortOnCannotGrowMemory(requestedSize) {
  3970. abort('Cannot enlarge memory arrays to size ' + requestedSize + ' bytes (OOM). Either (1) compile with -s INITIAL_MEMORY=X with X higher than the current value ' + HEAP8.length + ', (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ');
  3971. }
  3972. function _emscripten_resize_heap(requestedSize) {
  3973. var oldSize = HEAPU8.length;
  3974. requestedSize = requestedSize >>> 0;
  3975. abortOnCannotGrowMemory(requestedSize);
  3976. }
  3977. var ENV = {};
  3978. function getExecutableName() {
  3979. return thisProgram || './this.program';
  3980. }
  3981. function getEnvStrings() {
  3982. if (!getEnvStrings.strings) {
  3983. // Default values.
  3984. // Browser language detection #8751
  3985. var lang = ((typeof navigator == 'object' && navigator.languages && navigator.languages[0]) || 'C').replace('-', '_') + '.UTF-8';
  3986. var env = {
  3987. 'USER': 'web_user',
  3988. 'LOGNAME': 'web_user',
  3989. 'PATH': '/',
  3990. 'PWD': '/',
  3991. 'HOME': '/home/web_user',
  3992. 'LANG': lang,
  3993. '_': getExecutableName()
  3994. };
  3995. // Apply the user-provided values, if any.
  3996. for (var x in ENV) {
  3997. // x is a key in ENV; if ENV[x] is undefined, that means it was
  3998. // explicitly set to be so. We allow user code to do that to
  3999. // force variables with default values to remain unset.
  4000. if (ENV[x] === undefined) delete env[x];
  4001. else env[x] = ENV[x];
  4002. }
  4003. var strings = [];
  4004. for (var x in env) {
  4005. strings.push(x + '=' + env[x]);
  4006. }
  4007. getEnvStrings.strings = strings;
  4008. }
  4009. return getEnvStrings.strings;
  4010. }
  4011. function _environ_get(__environ, environ_buf) {
  4012. var bufSize = 0;
  4013. getEnvStrings().forEach(function(string, i) {
  4014. var ptr = environ_buf + bufSize;
  4015. HEAP32[(((__environ)+(i * 4))>>2)] = ptr;
  4016. writeAsciiToMemory(string, ptr);
  4017. bufSize += string.length + 1;
  4018. });
  4019. return 0;
  4020. }
  4021. function _environ_sizes_get(penviron_count, penviron_buf_size) {
  4022. var strings = getEnvStrings();
  4023. HEAP32[((penviron_count)>>2)] = strings.length;
  4024. var bufSize = 0;
  4025. strings.forEach(function(string) {
  4026. bufSize += string.length + 1;
  4027. });
  4028. HEAP32[((penviron_buf_size)>>2)] = bufSize;
  4029. return 0;
  4030. }
  4031. function _fd_close(fd) {
  4032. try {
  4033. var stream = SYSCALLS.getStreamFromFD(fd);
  4034. FS.close(stream);
  4035. return 0;
  4036. } catch (e) {
  4037. if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
  4038. return e.errno;
  4039. }
  4040. }
  4041. function _fd_read(fd, iov, iovcnt, pnum) {
  4042. try {
  4043. var stream = SYSCALLS.getStreamFromFD(fd);
  4044. var num = SYSCALLS.doReadv(stream, iov, iovcnt);
  4045. HEAP32[((pnum)>>2)] = num;
  4046. return 0;
  4047. } catch (e) {
  4048. if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
  4049. return e.errno;
  4050. }
  4051. }
  4052. function _fd_seek(fd, offset_low, offset_high, whence, newOffset) {
  4053. try {
  4054. var stream = SYSCALLS.getStreamFromFD(fd);
  4055. var HIGH_OFFSET = 0x100000000; // 2^32
  4056. // use an unsigned operator on low and shift high by 32-bits
  4057. var offset = offset_high * HIGH_OFFSET + (offset_low >>> 0);
  4058. var DOUBLE_LIMIT = 0x20000000000000; // 2^53
  4059. // we also check for equality since DOUBLE_LIMIT + 1 == DOUBLE_LIMIT
  4060. if (offset <= -DOUBLE_LIMIT || offset >= DOUBLE_LIMIT) {
  4061. return -61;
  4062. }
  4063. FS.llseek(stream, offset, whence);
  4064. (tempI64 = [stream.position>>>0,(tempDouble=stream.position,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((newOffset)>>2)] = tempI64[0],HEAP32[(((newOffset)+(4))>>2)] = tempI64[1]);
  4065. if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; // reset readdir state
  4066. return 0;
  4067. } catch (e) {
  4068. if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
  4069. return e.errno;
  4070. }
  4071. }
  4072. function _fd_write(fd, iov, iovcnt, pnum) {
  4073. try {
  4074. ;
  4075. var stream = SYSCALLS.getStreamFromFD(fd);
  4076. var num = SYSCALLS.doWritev(stream, iov, iovcnt);
  4077. HEAP32[((pnum)>>2)] = num;
  4078. return 0;
  4079. } catch (e) {
  4080. if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
  4081. return e.errno;
  4082. }
  4083. }
  4084. function _setTempRet0(val) {
  4085. setTempRet0(val);
  4086. }
  4087. function __isLeapYear(year) {
  4088. return year%4 === 0 && (year%100 !== 0 || year%400 === 0);
  4089. }
  4090. function __arraySum(array, index) {
  4091. var sum = 0;
  4092. for (var i = 0; i <= index; sum += array[i++]) {
  4093. // no-op
  4094. }
  4095. return sum;
  4096. }
  4097. var __MONTH_DAYS_LEAP = [31,29,31,30,31,30,31,31,30,31,30,31];
  4098. var __MONTH_DAYS_REGULAR = [31,28,31,30,31,30,31,31,30,31,30,31];
  4099. function __addDays(date, days) {
  4100. var newDate = new Date(date.getTime());
  4101. while (days > 0) {
  4102. var leap = __isLeapYear(newDate.getFullYear());
  4103. var currentMonth = newDate.getMonth();
  4104. var daysInCurrentMonth = (leap ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR)[currentMonth];
  4105. if (days > daysInCurrentMonth-newDate.getDate()) {
  4106. // we spill over to next month
  4107. days -= (daysInCurrentMonth-newDate.getDate()+1);
  4108. newDate.setDate(1);
  4109. if (currentMonth < 11) {
  4110. newDate.setMonth(currentMonth+1)
  4111. } else {
  4112. newDate.setMonth(0);
  4113. newDate.setFullYear(newDate.getFullYear()+1);
  4114. }
  4115. } else {
  4116. // we stay in current month
  4117. newDate.setDate(newDate.getDate()+days);
  4118. return newDate;
  4119. }
  4120. }
  4121. return newDate;
  4122. }
  4123. function _strftime(s, maxsize, format, tm) {
  4124. // size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, const struct tm *restrict timeptr);
  4125. // http://pubs.opengroup.org/onlinepubs/009695399/functions/strftime.html
  4126. var tm_zone = HEAP32[(((tm)+(40))>>2)];
  4127. var date = {
  4128. tm_sec: HEAP32[((tm)>>2)],
  4129. tm_min: HEAP32[(((tm)+(4))>>2)],
  4130. tm_hour: HEAP32[(((tm)+(8))>>2)],
  4131. tm_mday: HEAP32[(((tm)+(12))>>2)],
  4132. tm_mon: HEAP32[(((tm)+(16))>>2)],
  4133. tm_year: HEAP32[(((tm)+(20))>>2)],
  4134. tm_wday: HEAP32[(((tm)+(24))>>2)],
  4135. tm_yday: HEAP32[(((tm)+(28))>>2)],
  4136. tm_isdst: HEAP32[(((tm)+(32))>>2)],
  4137. tm_gmtoff: HEAP32[(((tm)+(36))>>2)],
  4138. tm_zone: tm_zone ? UTF8ToString(tm_zone) : ''
  4139. };
  4140. var pattern = UTF8ToString(format);
  4141. // expand format
  4142. var EXPANSION_RULES_1 = {
  4143. '%c': '%a %b %d %H:%M:%S %Y', // Replaced by the locale's appropriate date and time representation - e.g., Mon Aug 3 14:02:01 2013
  4144. '%D': '%m/%d/%y', // Equivalent to %m / %d / %y
  4145. '%F': '%Y-%m-%d', // Equivalent to %Y - %m - %d
  4146. '%h': '%b', // Equivalent to %b
  4147. '%r': '%I:%M:%S %p', // Replaced by the time in a.m. and p.m. notation
  4148. '%R': '%H:%M', // Replaced by the time in 24-hour notation
  4149. '%T': '%H:%M:%S', // Replaced by the time
  4150. '%x': '%m/%d/%y', // Replaced by the locale's appropriate date representation
  4151. '%X': '%H:%M:%S', // Replaced by the locale's appropriate time representation
  4152. // Modified Conversion Specifiers
  4153. '%Ec': '%c', // Replaced by the locale's alternative appropriate date and time representation.
  4154. '%EC': '%C', // Replaced by the name of the base year (period) in the locale's alternative representation.
  4155. '%Ex': '%m/%d/%y', // Replaced by the locale's alternative date representation.
  4156. '%EX': '%H:%M:%S', // Replaced by the locale's alternative time representation.
  4157. '%Ey': '%y', // Replaced by the offset from %EC (year only) in the locale's alternative representation.
  4158. '%EY': '%Y', // Replaced by the full alternative year representation.
  4159. '%Od': '%d', // Replaced by the day of the month, using the locale's alternative numeric symbols, filled as needed with leading zeros if there is any alternative symbol for zero; otherwise, with leading <space> characters.
  4160. '%Oe': '%e', // Replaced by the day of the month, using the locale's alternative numeric symbols, filled as needed with leading <space> characters.
  4161. '%OH': '%H', // Replaced by the hour (24-hour clock) using the locale's alternative numeric symbols.
  4162. '%OI': '%I', // Replaced by the hour (12-hour clock) using the locale's alternative numeric symbols.
  4163. '%Om': '%m', // Replaced by the month using the locale's alternative numeric symbols.
  4164. '%OM': '%M', // Replaced by the minutes using the locale's alternative numeric symbols.
  4165. '%OS': '%S', // Replaced by the seconds using the locale's alternative numeric symbols.
  4166. '%Ou': '%u', // Replaced by the weekday as a number in the locale's alternative representation (Monday=1).
  4167. '%OU': '%U', // Replaced by the week number of the year (Sunday as the first day of the week, rules corresponding to %U ) using the locale's alternative numeric symbols.
  4168. '%OV': '%V', // Replaced by the week number of the year (Monday as the first day of the week, rules corresponding to %V ) using the locale's alternative numeric symbols.
  4169. '%Ow': '%w', // Replaced by the number of the weekday (Sunday=0) using the locale's alternative numeric symbols.
  4170. '%OW': '%W', // Replaced by the week number of the year (Monday as the first day of the week) using the locale's alternative numeric symbols.
  4171. '%Oy': '%y', // Replaced by the year (offset from %C ) using the locale's alternative numeric symbols.
  4172. };
  4173. for (var rule in EXPANSION_RULES_1) {
  4174. pattern = pattern.replace(new RegExp(rule, 'g'), EXPANSION_RULES_1[rule]);
  4175. }
  4176. var WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
  4177. var MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
  4178. function leadingSomething(value, digits, character) {
  4179. var str = typeof value == 'number' ? value.toString() : (value || '');
  4180. while (str.length < digits) {
  4181. str = character[0]+str;
  4182. }
  4183. return str;
  4184. }
  4185. function leadingNulls(value, digits) {
  4186. return leadingSomething(value, digits, '0');
  4187. }
  4188. function compareByDay(date1, date2) {
  4189. function sgn(value) {
  4190. return value < 0 ? -1 : (value > 0 ? 1 : 0);
  4191. }
  4192. var compare;
  4193. if ((compare = sgn(date1.getFullYear()-date2.getFullYear())) === 0) {
  4194. if ((compare = sgn(date1.getMonth()-date2.getMonth())) === 0) {
  4195. compare = sgn(date1.getDate()-date2.getDate());
  4196. }
  4197. }
  4198. return compare;
  4199. }
  4200. function getFirstWeekStartDate(janFourth) {
  4201. switch (janFourth.getDay()) {
  4202. case 0: // Sunday
  4203. return new Date(janFourth.getFullYear()-1, 11, 29);
  4204. case 1: // Monday
  4205. return janFourth;
  4206. case 2: // Tuesday
  4207. return new Date(janFourth.getFullYear(), 0, 3);
  4208. case 3: // Wednesday
  4209. return new Date(janFourth.getFullYear(), 0, 2);
  4210. case 4: // Thursday
  4211. return new Date(janFourth.getFullYear(), 0, 1);
  4212. case 5: // Friday
  4213. return new Date(janFourth.getFullYear()-1, 11, 31);
  4214. case 6: // Saturday
  4215. return new Date(janFourth.getFullYear()-1, 11, 30);
  4216. }
  4217. }
  4218. function getWeekBasedYear(date) {
  4219. var thisDate = __addDays(new Date(date.tm_year+1900, 0, 1), date.tm_yday);
  4220. var janFourthThisYear = new Date(thisDate.getFullYear(), 0, 4);
  4221. var janFourthNextYear = new Date(thisDate.getFullYear()+1, 0, 4);
  4222. var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear);
  4223. var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear);
  4224. if (compareByDay(firstWeekStartThisYear, thisDate) <= 0) {
  4225. // this date is after the start of the first week of this year
  4226. if (compareByDay(firstWeekStartNextYear, thisDate) <= 0) {
  4227. return thisDate.getFullYear()+1;
  4228. } else {
  4229. return thisDate.getFullYear();
  4230. }
  4231. } else {
  4232. return thisDate.getFullYear()-1;
  4233. }
  4234. }
  4235. var EXPANSION_RULES_2 = {
  4236. '%a': function(date) {
  4237. return WEEKDAYS[date.tm_wday].substring(0,3);
  4238. },
  4239. '%A': function(date) {
  4240. return WEEKDAYS[date.tm_wday];
  4241. },
  4242. '%b': function(date) {
  4243. return MONTHS[date.tm_mon].substring(0,3);
  4244. },
  4245. '%B': function(date) {
  4246. return MONTHS[date.tm_mon];
  4247. },
  4248. '%C': function(date) {
  4249. var year = date.tm_year+1900;
  4250. return leadingNulls((year/100)|0,2);
  4251. },
  4252. '%d': function(date) {
  4253. return leadingNulls(date.tm_mday, 2);
  4254. },
  4255. '%e': function(date) {
  4256. return leadingSomething(date.tm_mday, 2, ' ');
  4257. },
  4258. '%g': function(date) {
  4259. // %g, %G, and %V give values according to the ISO 8601:2000 standard week-based year.
  4260. // In this system, weeks begin on a Monday and week 1 of the year is the week that includes
  4261. // January 4th, which is also the week that includes the first Thursday of the year, and
  4262. // is also the first week that contains at least four days in the year.
  4263. // If the first Monday of January is the 2nd, 3rd, or 4th, the preceding days are part of
  4264. // the last week of the preceding year; thus, for Saturday 2nd January 1999,
  4265. // %G is replaced by 1998 and %V is replaced by 53. If December 29th, 30th,
  4266. // or 31st is a Monday, it and any following days are part of week 1 of the following year.
  4267. // Thus, for Tuesday 30th December 1997, %G is replaced by 1998 and %V is replaced by 01.
  4268. return getWeekBasedYear(date).toString().substring(2);
  4269. },
  4270. '%G': function(date) {
  4271. return getWeekBasedYear(date);
  4272. },
  4273. '%H': function(date) {
  4274. return leadingNulls(date.tm_hour, 2);
  4275. },
  4276. '%I': function(date) {
  4277. var twelveHour = date.tm_hour;
  4278. if (twelveHour == 0) twelveHour = 12;
  4279. else if (twelveHour > 12) twelveHour -= 12;
  4280. return leadingNulls(twelveHour, 2);
  4281. },
  4282. '%j': function(date) {
  4283. // Day of the year (001-366)
  4284. return leadingNulls(date.tm_mday+__arraySum(__isLeapYear(date.tm_year+1900) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, date.tm_mon-1), 3);
  4285. },
  4286. '%m': function(date) {
  4287. return leadingNulls(date.tm_mon+1, 2);
  4288. },
  4289. '%M': function(date) {
  4290. return leadingNulls(date.tm_min, 2);
  4291. },
  4292. '%n': function() {
  4293. return '\n';
  4294. },
  4295. '%p': function(date) {
  4296. if (date.tm_hour >= 0 && date.tm_hour < 12) {
  4297. return 'AM';
  4298. } else {
  4299. return 'PM';
  4300. }
  4301. },
  4302. '%S': function(date) {
  4303. return leadingNulls(date.tm_sec, 2);
  4304. },
  4305. '%t': function() {
  4306. return '\t';
  4307. },
  4308. '%u': function(date) {
  4309. return date.tm_wday || 7;
  4310. },
  4311. '%U': function(date) {
  4312. // Replaced by the week number of the year as a decimal number [00,53].
  4313. // The first Sunday of January is the first day of week 1;
  4314. // days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
  4315. var janFirst = new Date(date.tm_year+1900, 0, 1);
  4316. var firstSunday = janFirst.getDay() === 0 ? janFirst : __addDays(janFirst, 7-janFirst.getDay());
  4317. var endDate = new Date(date.tm_year+1900, date.tm_mon, date.tm_mday);
  4318. // is target date after the first Sunday?
  4319. if (compareByDay(firstSunday, endDate) < 0) {
  4320. // calculate difference in days between first Sunday and endDate
  4321. var februaryFirstUntilEndMonth = __arraySum(__isLeapYear(endDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, endDate.getMonth()-1)-31;
  4322. var firstSundayUntilEndJanuary = 31-firstSunday.getDate();
  4323. var days = firstSundayUntilEndJanuary+februaryFirstUntilEndMonth+endDate.getDate();
  4324. return leadingNulls(Math.ceil(days/7), 2);
  4325. }
  4326. return compareByDay(firstSunday, janFirst) === 0 ? '01': '00';
  4327. },
  4328. '%V': function(date) {
  4329. // Replaced by the week number of the year (Monday as the first day of the week)
  4330. // as a decimal number [01,53]. If the week containing 1 January has four
  4331. // or more days in the new year, then it is considered week 1.
  4332. // Otherwise, it is the last week of the previous year, and the next week is week 1.
  4333. // Both January 4th and the first Thursday of January are always in week 1. [ tm_year, tm_wday, tm_yday]
  4334. var janFourthThisYear = new Date(date.tm_year+1900, 0, 4);
  4335. var janFourthNextYear = new Date(date.tm_year+1901, 0, 4);
  4336. var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear);
  4337. var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear);
  4338. var endDate = __addDays(new Date(date.tm_year+1900, 0, 1), date.tm_yday);
  4339. if (compareByDay(endDate, firstWeekStartThisYear) < 0) {
  4340. // if given date is before this years first week, then it belongs to the 53rd week of last year
  4341. return '53';
  4342. }
  4343. if (compareByDay(firstWeekStartNextYear, endDate) <= 0) {
  4344. // if given date is after next years first week, then it belongs to the 01th week of next year
  4345. return '01';
  4346. }
  4347. // given date is in between CW 01..53 of this calendar year
  4348. var daysDifference;
  4349. if (firstWeekStartThisYear.getFullYear() < date.tm_year+1900) {
  4350. // first CW of this year starts last year
  4351. daysDifference = date.tm_yday+32-firstWeekStartThisYear.getDate()
  4352. } else {
  4353. // first CW of this year starts this year
  4354. daysDifference = date.tm_yday+1-firstWeekStartThisYear.getDate();
  4355. }
  4356. return leadingNulls(Math.ceil(daysDifference/7), 2);
  4357. },
  4358. '%w': function(date) {
  4359. return date.tm_wday;
  4360. },
  4361. '%W': function(date) {
  4362. // Replaced by the week number of the year as a decimal number [00,53].
  4363. // The first Monday of January is the first day of week 1;
  4364. // days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
  4365. var janFirst = new Date(date.tm_year, 0, 1);
  4366. var firstMonday = janFirst.getDay() === 1 ? janFirst : __addDays(janFirst, janFirst.getDay() === 0 ? 1 : 7-janFirst.getDay()+1);
  4367. var endDate = new Date(date.tm_year+1900, date.tm_mon, date.tm_mday);
  4368. // is target date after the first Monday?
  4369. if (compareByDay(firstMonday, endDate) < 0) {
  4370. var februaryFirstUntilEndMonth = __arraySum(__isLeapYear(endDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, endDate.getMonth()-1)-31;
  4371. var firstMondayUntilEndJanuary = 31-firstMonday.getDate();
  4372. var days = firstMondayUntilEndJanuary+februaryFirstUntilEndMonth+endDate.getDate();
  4373. return leadingNulls(Math.ceil(days/7), 2);
  4374. }
  4375. return compareByDay(firstMonday, janFirst) === 0 ? '01': '00';
  4376. },
  4377. '%y': function(date) {
  4378. // Replaced by the last two digits of the year as a decimal number [00,99]. [ tm_year]
  4379. return (date.tm_year+1900).toString().substring(2);
  4380. },
  4381. '%Y': function(date) {
  4382. // Replaced by the year as a decimal number (for example, 1997). [ tm_year]
  4383. return date.tm_year+1900;
  4384. },
  4385. '%z': function(date) {
  4386. // Replaced by the offset from UTC in the ISO 8601:2000 standard format ( +hhmm or -hhmm ).
  4387. // For example, "-0430" means 4 hours 30 minutes behind UTC (west of Greenwich).
  4388. var off = date.tm_gmtoff;
  4389. var ahead = off >= 0;
  4390. off = Math.abs(off) / 60;
  4391. // convert from minutes into hhmm format (which means 60 minutes = 100 units)
  4392. off = (off / 60)*100 + (off % 60);
  4393. return (ahead ? '+' : '-') + String("0000" + off).slice(-4);
  4394. },
  4395. '%Z': function(date) {
  4396. return date.tm_zone;
  4397. },
  4398. '%%': function() {
  4399. return '%';
  4400. }
  4401. };
  4402. // Replace %% with a pair of NULLs (which cannot occur in a C string), then
  4403. // re-inject them after processing.
  4404. pattern = pattern.replace(/%%/g, '\0\0')
  4405. for (var rule in EXPANSION_RULES_2) {
  4406. if (pattern.includes(rule)) {
  4407. pattern = pattern.replace(new RegExp(rule, 'g'), EXPANSION_RULES_2[rule](date));
  4408. }
  4409. }
  4410. pattern = pattern.replace(/\0\0/g, '%')
  4411. var bytes = intArrayFromString(pattern, false);
  4412. if (bytes.length > maxsize) {
  4413. return 0;
  4414. }
  4415. writeArrayToMemory(bytes, s);
  4416. return bytes.length-1;
  4417. }
  4418. function _strftime_l(s, maxsize, format, tm) {
  4419. return _strftime(s, maxsize, format, tm); // no locale support yet
  4420. }
  4421. var FSNode = /** @constructor */ function(parent, name, mode, rdev) {
  4422. if (!parent) {
  4423. parent = this; // root node sets parent to itself
  4424. }
  4425. this.parent = parent;
  4426. this.mount = parent.mount;
  4427. this.mounted = null;
  4428. this.id = FS.nextInode++;
  4429. this.name = name;
  4430. this.mode = mode;
  4431. this.node_ops = {};
  4432. this.stream_ops = {};
  4433. this.rdev = rdev;
  4434. };
  4435. var readMode = 292/*292*/ | 73/*73*/;
  4436. var writeMode = 146/*146*/;
  4437. Object.defineProperties(FSNode.prototype, {
  4438. read: {
  4439. get: /** @this{FSNode} */function() {
  4440. return (this.mode & readMode) === readMode;
  4441. },
  4442. set: /** @this{FSNode} */function(val) {
  4443. val ? this.mode |= readMode : this.mode &= ~readMode;
  4444. }
  4445. },
  4446. write: {
  4447. get: /** @this{FSNode} */function() {
  4448. return (this.mode & writeMode) === writeMode;
  4449. },
  4450. set: /** @this{FSNode} */function(val) {
  4451. val ? this.mode |= writeMode : this.mode &= ~writeMode;
  4452. }
  4453. },
  4454. isFolder: {
  4455. get: /** @this{FSNode} */function() {
  4456. return FS.isDir(this.mode);
  4457. }
  4458. },
  4459. isDevice: {
  4460. get: /** @this{FSNode} */function() {
  4461. return FS.isChrdev(this.mode);
  4462. }
  4463. }
  4464. });
  4465. FS.FSNode = FSNode;
  4466. FS.staticInit();;
  4467. ERRNO_CODES = {
  4468. 'EPERM': 63,
  4469. 'ENOENT': 44,
  4470. 'ESRCH': 71,
  4471. 'EINTR': 27,
  4472. 'EIO': 29,
  4473. 'ENXIO': 60,
  4474. 'E2BIG': 1,
  4475. 'ENOEXEC': 45,
  4476. 'EBADF': 8,
  4477. 'ECHILD': 12,
  4478. 'EAGAIN': 6,
  4479. 'EWOULDBLOCK': 6,
  4480. 'ENOMEM': 48,
  4481. 'EACCES': 2,
  4482. 'EFAULT': 21,
  4483. 'ENOTBLK': 105,
  4484. 'EBUSY': 10,
  4485. 'EEXIST': 20,
  4486. 'EXDEV': 75,
  4487. 'ENODEV': 43,
  4488. 'ENOTDIR': 54,
  4489. 'EISDIR': 31,
  4490. 'EINVAL': 28,
  4491. 'ENFILE': 41,
  4492. 'EMFILE': 33,
  4493. 'ENOTTY': 59,
  4494. 'ETXTBSY': 74,
  4495. 'EFBIG': 22,
  4496. 'ENOSPC': 51,
  4497. 'ESPIPE': 70,
  4498. 'EROFS': 69,
  4499. 'EMLINK': 34,
  4500. 'EPIPE': 64,
  4501. 'EDOM': 18,
  4502. 'ERANGE': 68,
  4503. 'ENOMSG': 49,
  4504. 'EIDRM': 24,
  4505. 'ECHRNG': 106,
  4506. 'EL2NSYNC': 156,
  4507. 'EL3HLT': 107,
  4508. 'EL3RST': 108,
  4509. 'ELNRNG': 109,
  4510. 'EUNATCH': 110,
  4511. 'ENOCSI': 111,
  4512. 'EL2HLT': 112,
  4513. 'EDEADLK': 16,
  4514. 'ENOLCK': 46,
  4515. 'EBADE': 113,
  4516. 'EBADR': 114,
  4517. 'EXFULL': 115,
  4518. 'ENOANO': 104,
  4519. 'EBADRQC': 103,
  4520. 'EBADSLT': 102,
  4521. 'EDEADLOCK': 16,
  4522. 'EBFONT': 101,
  4523. 'ENOSTR': 100,
  4524. 'ENODATA': 116,
  4525. 'ETIME': 117,
  4526. 'ENOSR': 118,
  4527. 'ENONET': 119,
  4528. 'ENOPKG': 120,
  4529. 'EREMOTE': 121,
  4530. 'ENOLINK': 47,
  4531. 'EADV': 122,
  4532. 'ESRMNT': 123,
  4533. 'ECOMM': 124,
  4534. 'EPROTO': 65,
  4535. 'EMULTIHOP': 36,
  4536. 'EDOTDOT': 125,
  4537. 'EBADMSG': 9,
  4538. 'ENOTUNIQ': 126,
  4539. 'EBADFD': 127,
  4540. 'EREMCHG': 128,
  4541. 'ELIBACC': 129,
  4542. 'ELIBBAD': 130,
  4543. 'ELIBSCN': 131,
  4544. 'ELIBMAX': 132,
  4545. 'ELIBEXEC': 133,
  4546. 'ENOSYS': 52,
  4547. 'ENOTEMPTY': 55,
  4548. 'ENAMETOOLONG': 37,
  4549. 'ELOOP': 32,
  4550. 'EOPNOTSUPP': 138,
  4551. 'EPFNOSUPPORT': 139,
  4552. 'ECONNRESET': 15,
  4553. 'ENOBUFS': 42,
  4554. 'EAFNOSUPPORT': 5,
  4555. 'EPROTOTYPE': 67,
  4556. 'ENOTSOCK': 57,
  4557. 'ENOPROTOOPT': 50,
  4558. 'ESHUTDOWN': 140,
  4559. 'ECONNREFUSED': 14,
  4560. 'EADDRINUSE': 3,
  4561. 'ECONNABORTED': 13,
  4562. 'ENETUNREACH': 40,
  4563. 'ENETDOWN': 38,
  4564. 'ETIMEDOUT': 73,
  4565. 'EHOSTDOWN': 142,
  4566. 'EHOSTUNREACH': 23,
  4567. 'EINPROGRESS': 26,
  4568. 'EALREADY': 7,
  4569. 'EDESTADDRREQ': 17,
  4570. 'EMSGSIZE': 35,
  4571. 'EPROTONOSUPPORT': 66,
  4572. 'ESOCKTNOSUPPORT': 137,
  4573. 'EADDRNOTAVAIL': 4,
  4574. 'ENETRESET': 39,
  4575. 'EISCONN': 30,
  4576. 'ENOTCONN': 53,
  4577. 'ETOOMANYREFS': 141,
  4578. 'EUSERS': 136,
  4579. 'EDQUOT': 19,
  4580. 'ESTALE': 72,
  4581. 'ENOTSUP': 138,
  4582. 'ENOMEDIUM': 148,
  4583. 'EILSEQ': 25,
  4584. 'EOVERFLOW': 61,
  4585. 'ECANCELED': 11,
  4586. 'ENOTRECOVERABLE': 56,
  4587. 'EOWNERDEAD': 62,
  4588. 'ESTRPIPE': 135,
  4589. };;
  4590. var ASSERTIONS = true;
  4591. /** @type {function(string, boolean=, number=)} */
  4592. function intArrayFromString(stringy, dontAddNull, length) {
  4593. var len = length > 0 ? length : lengthBytesUTF8(stringy)+1;
  4594. var u8array = new Array(len);
  4595. var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
  4596. if (dontAddNull) u8array.length = numBytesWritten;
  4597. return u8array;
  4598. }
  4599. function intArrayToString(array) {
  4600. var ret = [];
  4601. for (var i = 0; i < array.length; i++) {
  4602. var chr = array[i];
  4603. if (chr > 0xFF) {
  4604. if (ASSERTIONS) {
  4605. assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ') at offset ' + i + ' not in 0x00-0xFF.');
  4606. }
  4607. chr &= 0xFF;
  4608. }
  4609. ret.push(String.fromCharCode(chr));
  4610. }
  4611. return ret.join('');
  4612. }
  4613. function checkIncomingModuleAPI() {
  4614. ignoredModuleProp('fetchSettings');
  4615. }
  4616. var asmLibraryArg = {
  4617. "__cxa_allocate_exception": ___cxa_allocate_exception,
  4618. "__cxa_throw": ___cxa_throw,
  4619. "__syscall_fcntl64": ___syscall_fcntl64,
  4620. "__syscall_ioctl": ___syscall_ioctl,
  4621. "__syscall_open": ___syscall_open,
  4622. "abort": _abort,
  4623. "emscripten_memcpy_big": _emscripten_memcpy_big,
  4624. "emscripten_resize_heap": _emscripten_resize_heap,
  4625. "environ_get": _environ_get,
  4626. "environ_sizes_get": _environ_sizes_get,
  4627. "fd_close": _fd_close,
  4628. "fd_read": _fd_read,
  4629. "fd_seek": _fd_seek,
  4630. "fd_write": _fd_write,
  4631. "setTempRet0": _setTempRet0,
  4632. "strftime_l": _strftime_l
  4633. };
  4634. var asm = createWasm();
  4635. /** @type {function(...*):?} */
  4636. var ___wasm_call_ctors = Module["___wasm_call_ctors"] = createExportWrapper("__wasm_call_ctors");
  4637. /** @type {function(...*):?} */
  4638. var _main = Module["_main"] = createExportWrapper("main");
  4639. /** @type {function(...*):?} */
  4640. var ___errno_location = Module["___errno_location"] = createExportWrapper("__errno_location");
  4641. /** @type {function(...*):?} */
  4642. var ___stdio_exit = Module["___stdio_exit"] = createExportWrapper("__stdio_exit");
  4643. /** @type {function(...*):?} */
  4644. var _malloc = Module["_malloc"] = createExportWrapper("malloc");
  4645. /** @type {function(...*):?} */
  4646. var _emscripten_stack_init = Module["_emscripten_stack_init"] = function() {
  4647. return (_emscripten_stack_init = Module["_emscripten_stack_init"] = Module["asm"]["emscripten_stack_init"]).apply(null, arguments);
  4648. };
  4649. /** @type {function(...*):?} */
  4650. var _emscripten_stack_get_free = Module["_emscripten_stack_get_free"] = function() {
  4651. return (_emscripten_stack_get_free = Module["_emscripten_stack_get_free"] = Module["asm"]["emscripten_stack_get_free"]).apply(null, arguments);
  4652. };
  4653. /** @type {function(...*):?} */
  4654. var _emscripten_stack_get_base = Module["_emscripten_stack_get_base"] = function() {
  4655. return (_emscripten_stack_get_base = Module["_emscripten_stack_get_base"] = Module["asm"]["emscripten_stack_get_base"]).apply(null, arguments);
  4656. };
  4657. /** @type {function(...*):?} */
  4658. var _emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = function() {
  4659. return (_emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = Module["asm"]["emscripten_stack_get_end"]).apply(null, arguments);
  4660. };
  4661. /** @type {function(...*):?} */
  4662. var stackSave = Module["stackSave"] = createExportWrapper("stackSave");
  4663. /** @type {function(...*):?} */
  4664. var stackRestore = Module["stackRestore"] = createExportWrapper("stackRestore");
  4665. /** @type {function(...*):?} */
  4666. var stackAlloc = Module["stackAlloc"] = createExportWrapper("stackAlloc");
  4667. /** @type {function(...*):?} */
  4668. var dynCall_jiji = Module["dynCall_jiji"] = createExportWrapper("dynCall_jiji");
  4669. /** @type {function(...*):?} */
  4670. var dynCall_viijii = Module["dynCall_viijii"] = createExportWrapper("dynCall_viijii");
  4671. /** @type {function(...*):?} */
  4672. var dynCall_iiiiij = Module["dynCall_iiiiij"] = createExportWrapper("dynCall_iiiiij");
  4673. /** @type {function(...*):?} */
  4674. var dynCall_iiiiijj = Module["dynCall_iiiiijj"] = createExportWrapper("dynCall_iiiiijj");
  4675. /** @type {function(...*):?} */
  4676. var dynCall_iiiiiijj = Module["dynCall_iiiiiijj"] = createExportWrapper("dynCall_iiiiiijj");
  4677. // === Auto-generated postamble setup entry stuff ===
  4678. unexportedRuntimeFunction('intArrayFromString', false);
  4679. unexportedRuntimeFunction('intArrayToString', false);
  4680. unexportedRuntimeFunction('ccall', false);
  4681. unexportedRuntimeFunction('cwrap', false);
  4682. unexportedRuntimeFunction('setValue', false);
  4683. unexportedRuntimeFunction('getValue', false);
  4684. unexportedRuntimeFunction('allocate', false);
  4685. unexportedRuntimeFunction('UTF8ArrayToString', false);
  4686. unexportedRuntimeFunction('UTF8ToString', false);
  4687. unexportedRuntimeFunction('stringToUTF8Array', false);
  4688. unexportedRuntimeFunction('stringToUTF8', false);
  4689. unexportedRuntimeFunction('lengthBytesUTF8', false);
  4690. unexportedRuntimeFunction('stackTrace', false);
  4691. unexportedRuntimeFunction('addOnPreRun', false);
  4692. unexportedRuntimeFunction('addOnInit', false);
  4693. unexportedRuntimeFunction('addOnPreMain', false);
  4694. unexportedRuntimeFunction('addOnExit', false);
  4695. unexportedRuntimeFunction('addOnPostRun', false);
  4696. unexportedRuntimeFunction('writeStringToMemory', false);
  4697. unexportedRuntimeFunction('writeArrayToMemory', false);
  4698. unexportedRuntimeFunction('writeAsciiToMemory', false);
  4699. unexportedRuntimeFunction('addRunDependency', true);
  4700. unexportedRuntimeFunction('removeRunDependency', true);
  4701. unexportedRuntimeFunction('FS_createFolder', false);
  4702. unexportedRuntimeFunction('FS_createPath', true);
  4703. unexportedRuntimeFunction('FS_createDataFile', true);
  4704. unexportedRuntimeFunction('FS_createPreloadedFile', true);
  4705. unexportedRuntimeFunction('FS_createLazyFile', true);
  4706. unexportedRuntimeFunction('FS_createLink', false);
  4707. unexportedRuntimeFunction('FS_createDevice', true);
  4708. unexportedRuntimeFunction('FS_unlink', true);
  4709. unexportedRuntimeFunction('getLEB', false);
  4710. unexportedRuntimeFunction('getFunctionTables', false);
  4711. unexportedRuntimeFunction('alignFunctionTables', false);
  4712. unexportedRuntimeFunction('registerFunctions', false);
  4713. unexportedRuntimeFunction('addFunction', false);
  4714. unexportedRuntimeFunction('removeFunction', false);
  4715. unexportedRuntimeFunction('getFuncWrapper', false);
  4716. unexportedRuntimeFunction('prettyPrint', false);
  4717. unexportedRuntimeFunction('dynCall', false);
  4718. unexportedRuntimeFunction('getCompilerSetting', false);
  4719. unexportedRuntimeFunction('print', false);
  4720. unexportedRuntimeFunction('printErr', false);
  4721. unexportedRuntimeFunction('getTempRet0', false);
  4722. unexportedRuntimeFunction('setTempRet0', false);
  4723. unexportedRuntimeFunction('callMain', false);
  4724. unexportedRuntimeFunction('abort', false);
  4725. unexportedRuntimeFunction('keepRuntimeAlive', false);
  4726. unexportedRuntimeFunction('zeroMemory', false);
  4727. unexportedRuntimeFunction('stringToNewUTF8', false);
  4728. unexportedRuntimeFunction('abortOnCannotGrowMemory', false);
  4729. unexportedRuntimeFunction('emscripten_realloc_buffer', false);
  4730. unexportedRuntimeFunction('ENV', false);
  4731. unexportedRuntimeFunction('withStackSave', false);
  4732. unexportedRuntimeFunction('ERRNO_CODES', false);
  4733. unexportedRuntimeFunction('ERRNO_MESSAGES', false);
  4734. unexportedRuntimeFunction('setErrNo', false);
  4735. unexportedRuntimeFunction('inetPton4', false);
  4736. unexportedRuntimeFunction('inetNtop4', false);
  4737. unexportedRuntimeFunction('inetPton6', false);
  4738. unexportedRuntimeFunction('inetNtop6', false);
  4739. unexportedRuntimeFunction('readSockaddr', false);
  4740. unexportedRuntimeFunction('writeSockaddr', false);
  4741. unexportedRuntimeFunction('DNS', false);
  4742. unexportedRuntimeFunction('getHostByName', false);
  4743. unexportedRuntimeFunction('Protocols', false);
  4744. unexportedRuntimeFunction('Sockets', false);
  4745. unexportedRuntimeFunction('getRandomDevice', false);
  4746. unexportedRuntimeFunction('traverseStack', false);
  4747. unexportedRuntimeFunction('convertFrameToPC', false);
  4748. unexportedRuntimeFunction('UNWIND_CACHE', false);
  4749. unexportedRuntimeFunction('saveInUnwindCache', false);
  4750. unexportedRuntimeFunction('convertPCtoSourceLocation', false);
  4751. unexportedRuntimeFunction('readAsmConstArgsArray', false);
  4752. unexportedRuntimeFunction('readAsmConstArgs', false);
  4753. unexportedRuntimeFunction('mainThreadEM_ASM', false);
  4754. unexportedRuntimeFunction('jstoi_q', false);
  4755. unexportedRuntimeFunction('jstoi_s', false);
  4756. unexportedRuntimeFunction('getExecutableName', false);
  4757. unexportedRuntimeFunction('listenOnce', false);
  4758. unexportedRuntimeFunction('autoResumeAudioContext', false);
  4759. unexportedRuntimeFunction('dynCallLegacy', false);
  4760. unexportedRuntimeFunction('getDynCaller', false);
  4761. unexportedRuntimeFunction('dynCall', false);
  4762. unexportedRuntimeFunction('callRuntimeCallbacks', false);
  4763. unexportedRuntimeFunction('wasmTableMirror', false);
  4764. unexportedRuntimeFunction('setWasmTableEntry', false);
  4765. unexportedRuntimeFunction('getWasmTableEntry', false);
  4766. unexportedRuntimeFunction('handleException', false);
  4767. unexportedRuntimeFunction('runtimeKeepalivePush', false);
  4768. unexportedRuntimeFunction('runtimeKeepalivePop', false);
  4769. unexportedRuntimeFunction('callUserCallback', false);
  4770. unexportedRuntimeFunction('maybeExit', false);
  4771. unexportedRuntimeFunction('safeSetTimeout', false);
  4772. unexportedRuntimeFunction('asmjsMangle', false);
  4773. unexportedRuntimeFunction('asyncLoad', false);
  4774. unexportedRuntimeFunction('alignMemory', false);
  4775. unexportedRuntimeFunction('mmapAlloc', false);
  4776. unexportedRuntimeFunction('reallyNegative', false);
  4777. unexportedRuntimeFunction('unSign', false);
  4778. unexportedRuntimeFunction('reSign', false);
  4779. unexportedRuntimeFunction('formatString', false);
  4780. unexportedRuntimeFunction('PATH', false);
  4781. unexportedRuntimeFunction('PATH_FS', false);
  4782. unexportedRuntimeFunction('SYSCALLS', false);
  4783. unexportedRuntimeFunction('getSocketFromFD', false);
  4784. unexportedRuntimeFunction('getSocketAddress', false);
  4785. unexportedRuntimeFunction('JSEvents', false);
  4786. unexportedRuntimeFunction('registerKeyEventCallback', false);
  4787. unexportedRuntimeFunction('specialHTMLTargets', false);
  4788. unexportedRuntimeFunction('maybeCStringToJsString', false);
  4789. unexportedRuntimeFunction('findEventTarget', false);
  4790. unexportedRuntimeFunction('findCanvasEventTarget', false);
  4791. unexportedRuntimeFunction('getBoundingClientRect', false);
  4792. unexportedRuntimeFunction('fillMouseEventData', false);
  4793. unexportedRuntimeFunction('registerMouseEventCallback', false);
  4794. unexportedRuntimeFunction('registerWheelEventCallback', false);
  4795. unexportedRuntimeFunction('registerUiEventCallback', false);
  4796. unexportedRuntimeFunction('registerFocusEventCallback', false);
  4797. unexportedRuntimeFunction('fillDeviceOrientationEventData', false);
  4798. unexportedRuntimeFunction('registerDeviceOrientationEventCallback', false);
  4799. unexportedRuntimeFunction('fillDeviceMotionEventData', false);
  4800. unexportedRuntimeFunction('registerDeviceMotionEventCallback', false);
  4801. unexportedRuntimeFunction('screenOrientation', false);
  4802. unexportedRuntimeFunction('fillOrientationChangeEventData', false);
  4803. unexportedRuntimeFunction('registerOrientationChangeEventCallback', false);
  4804. unexportedRuntimeFunction('fillFullscreenChangeEventData', false);
  4805. unexportedRuntimeFunction('registerFullscreenChangeEventCallback', false);
  4806. unexportedRuntimeFunction('registerRestoreOldStyle', false);
  4807. unexportedRuntimeFunction('hideEverythingExceptGivenElement', false);
  4808. unexportedRuntimeFunction('restoreHiddenElements', false);
  4809. unexportedRuntimeFunction('setLetterbox', false);
  4810. unexportedRuntimeFunction('currentFullscreenStrategy', false);
  4811. unexportedRuntimeFunction('restoreOldWindowedStyle', false);
  4812. unexportedRuntimeFunction('softFullscreenResizeWebGLRenderTarget', false);
  4813. unexportedRuntimeFunction('doRequestFullscreen', false);
  4814. unexportedRuntimeFunction('fillPointerlockChangeEventData', false);
  4815. unexportedRuntimeFunction('registerPointerlockChangeEventCallback', false);
  4816. unexportedRuntimeFunction('registerPointerlockErrorEventCallback', false);
  4817. unexportedRuntimeFunction('requestPointerLock', false);
  4818. unexportedRuntimeFunction('fillVisibilityChangeEventData', false);
  4819. unexportedRuntimeFunction('registerVisibilityChangeEventCallback', false);
  4820. unexportedRuntimeFunction('registerTouchEventCallback', false);
  4821. unexportedRuntimeFunction('fillGamepadEventData', false);
  4822. unexportedRuntimeFunction('registerGamepadEventCallback', false);
  4823. unexportedRuntimeFunction('registerBeforeUnloadEventCallback', false);
  4824. unexportedRuntimeFunction('fillBatteryEventData', false);
  4825. unexportedRuntimeFunction('battery', false);
  4826. unexportedRuntimeFunction('registerBatteryEventCallback', false);
  4827. unexportedRuntimeFunction('setCanvasElementSize', false);
  4828. unexportedRuntimeFunction('getCanvasElementSize', false);
  4829. unexportedRuntimeFunction('demangle', false);
  4830. unexportedRuntimeFunction('demangleAll', false);
  4831. unexportedRuntimeFunction('jsStackTrace', false);
  4832. unexportedRuntimeFunction('stackTrace', false);
  4833. unexportedRuntimeFunction('getEnvStrings', false);
  4834. unexportedRuntimeFunction('checkWasiClock', false);
  4835. unexportedRuntimeFunction('writeI53ToI64', false);
  4836. unexportedRuntimeFunction('writeI53ToI64Clamped', false);
  4837. unexportedRuntimeFunction('writeI53ToI64Signaling', false);
  4838. unexportedRuntimeFunction('writeI53ToU64Clamped', false);
  4839. unexportedRuntimeFunction('writeI53ToU64Signaling', false);
  4840. unexportedRuntimeFunction('readI53FromI64', false);
  4841. unexportedRuntimeFunction('readI53FromU64', false);
  4842. unexportedRuntimeFunction('convertI32PairToI53', false);
  4843. unexportedRuntimeFunction('convertU32PairToI53', false);
  4844. unexportedRuntimeFunction('setImmediateWrapped', false);
  4845. unexportedRuntimeFunction('clearImmediateWrapped', false);
  4846. unexportedRuntimeFunction('polyfillSetImmediate', false);
  4847. unexportedRuntimeFunction('uncaughtExceptionCount', false);
  4848. unexportedRuntimeFunction('exceptionLast', false);
  4849. unexportedRuntimeFunction('exceptionCaught', false);
  4850. unexportedRuntimeFunction('ExceptionInfo', false);
  4851. unexportedRuntimeFunction('CatchInfo', false);
  4852. unexportedRuntimeFunction('exception_addRef', false);
  4853. unexportedRuntimeFunction('exception_decRef', false);
  4854. unexportedRuntimeFunction('Browser', false);
  4855. unexportedRuntimeFunction('funcWrappers', false);
  4856. unexportedRuntimeFunction('getFuncWrapper', false);
  4857. unexportedRuntimeFunction('setMainLoop', false);
  4858. unexportedRuntimeFunction('wget', false);
  4859. unexportedRuntimeFunction('FS', false);
  4860. unexportedRuntimeFunction('MEMFS', false);
  4861. unexportedRuntimeFunction('TTY', false);
  4862. unexportedRuntimeFunction('PIPEFS', false);
  4863. unexportedRuntimeFunction('SOCKFS', false);
  4864. unexportedRuntimeFunction('_setNetworkCallback', false);
  4865. unexportedRuntimeFunction('tempFixedLengthArray', false);
  4866. unexportedRuntimeFunction('miniTempWebGLFloatBuffers', false);
  4867. unexportedRuntimeFunction('heapObjectForWebGLType', false);
  4868. unexportedRuntimeFunction('heapAccessShiftForWebGLHeap', false);
  4869. unexportedRuntimeFunction('GL', false);
  4870. unexportedRuntimeFunction('emscriptenWebGLGet', false);
  4871. unexportedRuntimeFunction('computeUnpackAlignedImageSize', false);
  4872. unexportedRuntimeFunction('emscriptenWebGLGetTexPixelData', false);
  4873. unexportedRuntimeFunction('emscriptenWebGLGetUniform', false);
  4874. unexportedRuntimeFunction('webglGetUniformLocation', false);
  4875. unexportedRuntimeFunction('webglPrepareUniformLocationsBeforeFirstUse', false);
  4876. unexportedRuntimeFunction('webglGetLeftBracePos', false);
  4877. unexportedRuntimeFunction('emscriptenWebGLGetVertexAttrib', false);
  4878. unexportedRuntimeFunction('writeGLArray', false);
  4879. unexportedRuntimeFunction('AL', false);
  4880. unexportedRuntimeFunction('SDL_unicode', false);
  4881. unexportedRuntimeFunction('SDL_ttfContext', false);
  4882. unexportedRuntimeFunction('SDL_audio', false);
  4883. unexportedRuntimeFunction('SDL', false);
  4884. unexportedRuntimeFunction('SDL_gfx', false);
  4885. unexportedRuntimeFunction('GLUT', false);
  4886. unexportedRuntimeFunction('EGL', false);
  4887. unexportedRuntimeFunction('GLFW_Window', false);
  4888. unexportedRuntimeFunction('GLFW', false);
  4889. unexportedRuntimeFunction('GLEW', false);
  4890. unexportedRuntimeFunction('IDBStore', false);
  4891. unexportedRuntimeFunction('runAndAbortIfError', false);
  4892. unexportedRuntimeFunction('warnOnce', false);
  4893. unexportedRuntimeFunction('stackSave', false);
  4894. unexportedRuntimeFunction('stackRestore', false);
  4895. unexportedRuntimeFunction('stackAlloc', false);
  4896. unexportedRuntimeFunction('AsciiToString', false);
  4897. unexportedRuntimeFunction('stringToAscii', false);
  4898. unexportedRuntimeFunction('UTF16ToString', false);
  4899. unexportedRuntimeFunction('stringToUTF16', false);
  4900. unexportedRuntimeFunction('lengthBytesUTF16', false);
  4901. unexportedRuntimeFunction('UTF32ToString', false);
  4902. unexportedRuntimeFunction('stringToUTF32', false);
  4903. unexportedRuntimeFunction('lengthBytesUTF32', false);
  4904. unexportedRuntimeFunction('allocateUTF8', false);
  4905. unexportedRuntimeFunction('allocateUTF8OnStack', false);
  4906. Module["writeStackCookie"] = writeStackCookie;
  4907. Module["checkStackCookie"] = checkStackCookie;
  4908. unexportedRuntimeSymbol('ALLOC_NORMAL', false);
  4909. unexportedRuntimeSymbol('ALLOC_STACK', false);
  4910. var calledRun;
  4911. /**
  4912. * @constructor
  4913. * @this {ExitStatus}
  4914. */
  4915. function ExitStatus(status) {
  4916. this.name = "ExitStatus";
  4917. this.message = "Program terminated with exit(" + status + ")";
  4918. this.status = status;
  4919. }
  4920. var calledMain = false;
  4921. dependenciesFulfilled = function runCaller() {
  4922. // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
  4923. if (!calledRun) run();
  4924. if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
  4925. };
  4926. function callMain(args) {
  4927. assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])');
  4928. assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
  4929. var entryFunction = Module['_main'];
  4930. args = args || [];
  4931. var argc = args.length+1;
  4932. var argv = stackAlloc((argc + 1) * 4);
  4933. HEAP32[argv >> 2] = allocateUTF8OnStack(thisProgram);
  4934. for (var i = 1; i < argc; i++) {
  4935. HEAP32[(argv >> 2) + i] = allocateUTF8OnStack(args[i - 1]);
  4936. }
  4937. HEAP32[(argv >> 2) + argc] = 0;
  4938. try {
  4939. var ret = entryFunction(argc, argv);
  4940. // In PROXY_TO_PTHREAD builds, we should never exit the runtime below, as
  4941. // execution is asynchronously handed off to a pthread.
  4942. // if we're not running an evented main loop, it's time to exit
  4943. exit(ret, /* implicit = */ true);
  4944. return ret;
  4945. }
  4946. catch (e) {
  4947. return handleException(e);
  4948. } finally {
  4949. calledMain = true;
  4950. }
  4951. }
  4952. function stackCheckInit() {
  4953. // This is normally called automatically during __wasm_call_ctors but need to
  4954. // get these values before even running any of the ctors so we call it redundantly
  4955. // here.
  4956. // TODO(sbc): Move writeStackCookie to native to to avoid this.
  4957. _emscripten_stack_init();
  4958. writeStackCookie();
  4959. }
  4960. /** @type {function(Array=)} */
  4961. function run(args) {
  4962. args = args || arguments_;
  4963. if (runDependencies > 0) {
  4964. return;
  4965. }
  4966. stackCheckInit();
  4967. preRun();
  4968. // a preRun added a dependency, run will be called later
  4969. if (runDependencies > 0) {
  4970. return;
  4971. }
  4972. function doRun() {
  4973. // run may have just been called through dependencies being fulfilled just in this very frame,
  4974. // or while the async setStatus time below was happening
  4975. if (calledRun) return;
  4976. calledRun = true;
  4977. Module['calledRun'] = true;
  4978. if (ABORT) return;
  4979. initRuntime();
  4980. preMain();
  4981. if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized']();
  4982. if (shouldRunNow) callMain(args);
  4983. postRun();
  4984. }
  4985. if (Module['setStatus']) {
  4986. Module['setStatus']('Running...');
  4987. setTimeout(function() {
  4988. setTimeout(function() {
  4989. Module['setStatus']('');
  4990. }, 1);
  4991. doRun();
  4992. }, 1);
  4993. } else
  4994. {
  4995. doRun();
  4996. }
  4997. checkStackCookie();
  4998. }
  4999. Module['run'] = run;
  5000. function checkUnflushedContent() {
  5001. // Compiler settings do not allow exiting the runtime, so flushing
  5002. // the streams is not possible. but in ASSERTIONS mode we check
  5003. // if there was something to flush, and if so tell the user they
  5004. // should request that the runtime be exitable.
  5005. // Normally we would not even include flush() at all, but in ASSERTIONS
  5006. // builds we do so just for this check, and here we see if there is any
  5007. // content to flush, that is, we check if there would have been
  5008. // something a non-ASSERTIONS build would have not seen.
  5009. // How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=0
  5010. // mode (which has its own special function for this; otherwise, all
  5011. // the code is inside libc)
  5012. var oldOut = out;
  5013. var oldErr = err;
  5014. var has = false;
  5015. out = err = (x) => {
  5016. has = true;
  5017. }
  5018. try { // it doesn't matter if it fails
  5019. ___stdio_exit();
  5020. // also flush in the JS FS layer
  5021. ['stdout', 'stderr'].forEach(function(name) {
  5022. var info = FS.analyzePath('/dev/' + name);
  5023. if (!info) return;
  5024. var stream = info.object;
  5025. var rdev = stream.rdev;
  5026. var tty = TTY.ttys[rdev];
  5027. if (tty && tty.output && tty.output.length) {
  5028. has = true;
  5029. }
  5030. });
  5031. } catch(e) {}
  5032. out = oldOut;
  5033. err = oldErr;
  5034. if (has) {
  5035. warnOnce('stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the FAQ), or make sure to emit a newline when you printf etc.');
  5036. }
  5037. }
  5038. /** @param {boolean|number=} implicit */
  5039. function exit(status, implicit) {
  5040. EXITSTATUS = status;
  5041. // Skip this check if the runtime is being kept alive deliberately.
  5042. // For example if `exit_with_live_runtime` is called.
  5043. if (!runtimeKeepaliveCounter) {
  5044. checkUnflushedContent();
  5045. }
  5046. if (keepRuntimeAlive()) {
  5047. // if exit() was called, we may warn the user if the runtime isn't actually being shut down
  5048. if (!implicit) {
  5049. var msg = 'program exited (with status: ' + status + '), but EXIT_RUNTIME is not set, so halting execution but not exiting the runtime or preventing further async execution (build with EXIT_RUNTIME=1, if you want a true shutdown)';
  5050. err(msg);
  5051. }
  5052. } else {
  5053. exitRuntime();
  5054. }
  5055. procExit(status);
  5056. }
  5057. function procExit(code) {
  5058. EXITSTATUS = code;
  5059. if (!keepRuntimeAlive()) {
  5060. if (Module['onExit']) Module['onExit'](code);
  5061. ABORT = true;
  5062. }
  5063. quit_(code, new ExitStatus(code));
  5064. }
  5065. if (Module['preInit']) {
  5066. if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
  5067. while (Module['preInit'].length > 0) {
  5068. Module['preInit'].pop()();
  5069. }
  5070. }
  5071. // shouldRunNow refers to calling main(), not run().
  5072. var shouldRunNow = true;
  5073. if (Module['noInitialRun']) shouldRunNow = false;
  5074. run();