Guest User

texlive.js 2020 pdftex.bc

a guest
Jun 2nd, 2020
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 259.86 KB | None | 0 0
  1. /**
  2. * @license
  3. * Copyright 2010 The Emscripten Authors
  4. * SPDX-License-Identifier: MIT
  5. */
  6.  
  7. // The Module object: Our interface to the outside world. We import
  8. // and export values on it. There are various ways Module can be used:
  9. // 1. Not defined. We create it here
  10. // 2. A function parameter, function(Module) { ..generated code.. }
  11. // 3. pre-run appended it, var Module = {}; ..generated code..
  12. // 4. External script tag defines var Module.
  13. // We need to check if Module already exists (e.g. case 3 above).
  14. // Substitution will be replaced with actual code on later stage of the build,
  15. // this way Closure Compiler will not mangle it (e.g. case 4. above).
  16. // Note that if you want to run closure, and also to use Module
  17. // after the generated code, you will need to define var Module = {};
  18. // before the code. Then that object will be used in the code, and you
  19. // can continue to use Module afterwards as well.
  20. var Module = typeof Module !== 'undefined' ? Module : {};
  21.  
  22.  
  23. // --pre-jses are emitted after the Module integration code, so that they can
  24. // refer to Module (if they choose; they can also define Module)
  25. // {{PRE_JSES}}
  26.  
  27. // Sometimes an existing Module object exists with properties
  28. // meant to overwrite the default module functionality. Here
  29. // we collect those properties and reapply _after_ we configure
  30. // the current environment's defaults to avoid having to be so
  31. // defensive during initialization.
  32. var moduleOverrides = {};
  33. var key;
  34. for (key in Module) {
  35. if (Module.hasOwnProperty(key)) {
  36. moduleOverrides[key] = Module[key];
  37. }
  38. }
  39.  
  40. var arguments_ = [];
  41. var thisProgram = './this.program';
  42. var quit_ = function(status, toThrow) {
  43. throw toThrow;
  44. };
  45.  
  46. // Determine the runtime environment we are in. You can customize this by
  47. // setting the ENVIRONMENT setting at compile time (see settings.js).
  48.  
  49. var ENVIRONMENT_IS_WEB = false;
  50. var ENVIRONMENT_IS_WORKER = false;
  51. var ENVIRONMENT_IS_NODE = false;
  52. var ENVIRONMENT_IS_SHELL = false;
  53. ENVIRONMENT_IS_WEB = typeof window === 'object';
  54. ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
  55. // N.b. Electron.js environment is simultaneously a NODE-environment, but
  56. // also a web environment.
  57. ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string';
  58. ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
  59.  
  60.  
  61.  
  62.  
  63. // `/` should be present at the end if `scriptDirectory` is not empty
  64. var scriptDirectory = '';
  65. function locateFile(path) {
  66. if (Module['locateFile']) {
  67. return Module['locateFile'](path, scriptDirectory);
  68. }
  69. return scriptDirectory + path;
  70. }
  71.  
  72. // Hooks that are implemented differently in different runtime environments.
  73. var read_,
  74. readAsync,
  75. readBinary,
  76. setWindowTitle;
  77.  
  78. var nodeFS;
  79. var nodePath;
  80.  
  81. if (ENVIRONMENT_IS_NODE) {
  82. if (ENVIRONMENT_IS_WORKER) {
  83. scriptDirectory = require('path').dirname(scriptDirectory) + '/';
  84. } else {
  85. scriptDirectory = __dirname + '/';
  86. }
  87.  
  88.  
  89. /**
  90. * @license
  91. * Copyright 2019 The Emscripten Authors
  92. * SPDX-License-Identifier: MIT
  93. */
  94.  
  95. read_ = function shell_read(filename, binary) {
  96. if (!nodeFS) nodeFS = require('fs');
  97. if (!nodePath) nodePath = require('path');
  98. filename = nodePath['normalize'](filename);
  99. return nodeFS['readFileSync'](filename, binary ? null : 'utf8');
  100. };
  101.  
  102. readBinary = function readBinary(filename) {
  103. var ret = read_(filename, true);
  104. if (!ret.buffer) {
  105. ret = new Uint8Array(ret);
  106. }
  107. assert(ret.buffer);
  108. return ret;
  109. };
  110.  
  111.  
  112.  
  113.  
  114. if (process['argv'].length > 1) {
  115. thisProgram = process['argv'][1].replace(/\\/g, '/');
  116. }
  117.  
  118. arguments_ = process['argv'].slice(2);
  119.  
  120. if (typeof module !== 'undefined') {
  121. module['exports'] = Module;
  122. }
  123.  
  124. process['on']('uncaughtException', function(ex) {
  125. // suppress ExitStatus exceptions from showing an error
  126. if (!(ex instanceof ExitStatus)) {
  127. throw ex;
  128. }
  129. });
  130.  
  131. process['on']('unhandledRejection', abort);
  132.  
  133. quit_ = function(status) {
  134. process['exit'](status);
  135. };
  136.  
  137. Module['inspect'] = function () { return '[Emscripten Module object]'; };
  138.  
  139.  
  140.  
  141. } else
  142. if (ENVIRONMENT_IS_SHELL) {
  143.  
  144.  
  145. if (typeof read != 'undefined') {
  146. read_ = function shell_read(f) {
  147. return read(f);
  148. };
  149. }
  150.  
  151. readBinary = function readBinary(f) {
  152. var data;
  153. if (typeof readbuffer === 'function') {
  154. return new Uint8Array(readbuffer(f));
  155. }
  156. data = read(f, 'binary');
  157. assert(typeof data === 'object');
  158. return data;
  159. };
  160.  
  161. if (typeof scriptArgs != 'undefined') {
  162. arguments_ = scriptArgs;
  163. } else if (typeof arguments != 'undefined') {
  164. arguments_ = arguments;
  165. }
  166.  
  167. if (typeof quit === 'function') {
  168. quit_ = function(status) {
  169. quit(status);
  170. };
  171. }
  172.  
  173. if (typeof print !== 'undefined') {
  174. // Prefer to use print/printErr where they exist, as they usually work better.
  175. if (typeof console === 'undefined') console = /** @type{!Console} */({});
  176. console.log = /** @type{!function(this:Console, ...*): undefined} */ (print);
  177. console.warn = console.error = /** @type{!function(this:Console, ...*): undefined} */ (typeof printErr !== 'undefined' ? printErr : print);
  178. }
  179.  
  180.  
  181. } else
  182.  
  183. // Note that this includes Node.js workers when relevant (pthreads is enabled).
  184. // Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
  185. // ENVIRONMENT_IS_NODE.
  186. if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
  187. if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled
  188. scriptDirectory = self.location.href;
  189. } else if (document.currentScript) { // web
  190. scriptDirectory = document.currentScript.src;
  191. }
  192. // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
  193. // otherwise, slice off the final part of the url to find the script directory.
  194. // if scriptDirectory does not contain a slash, lastIndexOf will return -1,
  195. // and scriptDirectory will correctly be replaced with an empty string.
  196. if (scriptDirectory.indexOf('blob:') !== 0) {
  197. scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf('/')+1);
  198. } else {
  199. scriptDirectory = '';
  200. }
  201.  
  202.  
  203. // Differentiate the Web Worker from the Node Worker case, as reading must
  204. // be done differently.
  205. {
  206.  
  207.  
  208. /**
  209. * @license
  210. * Copyright 2019 The Emscripten Authors
  211. * SPDX-License-Identifier: MIT
  212. */
  213.  
  214. read_ = function shell_read(url) {
  215. var xhr = new XMLHttpRequest();
  216. xhr.open('GET', url, false);
  217. xhr.send(null);
  218. return xhr.responseText;
  219. };
  220.  
  221. if (ENVIRONMENT_IS_WORKER) {
  222. readBinary = function readBinary(url) {
  223. var xhr = new XMLHttpRequest();
  224. xhr.open('GET', url, false);
  225. xhr.responseType = 'arraybuffer';
  226. xhr.send(null);
  227. return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));
  228. };
  229. }
  230.  
  231. readAsync = function readAsync(url, onload, onerror) {
  232. var xhr = new XMLHttpRequest();
  233. xhr.open('GET', url, true);
  234. xhr.responseType = 'arraybuffer';
  235. xhr.onload = function xhr_onload() {
  236. if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
  237. onload(xhr.response);
  238. return;
  239. }
  240. onerror();
  241. };
  242. xhr.onerror = onerror;
  243. xhr.send(null);
  244. };
  245.  
  246.  
  247.  
  248.  
  249. }
  250.  
  251. setWindowTitle = function(title) { document.title = title };
  252. } else
  253. {
  254. }
  255.  
  256.  
  257. // Set up the out() and err() hooks, which are how we can print to stdout or
  258. // stderr, respectively.
  259. var out = Module['print'] || console.log.bind(console);
  260. var err = Module['printErr'] || console.warn.bind(console);
  261.  
  262. // Merge back in the overrides
  263. for (key in moduleOverrides) {
  264. if (moduleOverrides.hasOwnProperty(key)) {
  265. Module[key] = moduleOverrides[key];
  266. }
  267. }
  268. // Free the object hierarchy contained in the overrides, this lets the GC
  269. // reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.
  270. moduleOverrides = null;
  271.  
  272. // Emit code to handle expected values on the Module object. This applies Module.x
  273. // to the proper local x. This has two benefits: first, we only emit it if it is
  274. // expected to arrive, and second, by using a local everywhere else that can be
  275. // minified.
  276. if (Module['arguments']) arguments_ = Module['arguments'];
  277. if (Module['thisProgram']) thisProgram = Module['thisProgram'];
  278. if (Module['quit']) quit_ = Module['quit'];
  279.  
  280. // perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
  281.  
  282.  
  283.  
  284. /**
  285. * @license
  286. * Copyright 2017 The Emscripten Authors
  287. * SPDX-License-Identifier: MIT
  288. */
  289.  
  290. // {{PREAMBLE_ADDITIONS}}
  291.  
  292. var STACK_ALIGN = 16;
  293.  
  294.  
  295. function dynamicAlloc(size) {
  296. var ret = HEAP32[DYNAMICTOP_PTR>>2];
  297. var end = (ret + size + 15) & -16;
  298. HEAP32[DYNAMICTOP_PTR>>2] = end;
  299. return ret;
  300. }
  301.  
  302. function alignMemory(size, factor) {
  303. if (!factor) factor = STACK_ALIGN; // stack alignment (16-byte) by default
  304. return Math.ceil(size / factor) * factor;
  305. }
  306.  
  307. function getNativeTypeSize(type) {
  308. switch (type) {
  309. case 'i1': case 'i8': return 1;
  310. case 'i16': return 2;
  311. case 'i32': return 4;
  312. case 'i64': return 8;
  313. case 'float': return 4;
  314. case 'double': return 8;
  315. default: {
  316. if (type[type.length-1] === '*') {
  317. return 4; // A pointer
  318. } else if (type[0] === 'i') {
  319. var bits = Number(type.substr(1));
  320. assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type);
  321. return bits / 8;
  322. } else {
  323. return 0;
  324. }
  325. }
  326. }
  327. }
  328.  
  329. function warnOnce(text) {
  330. if (!warnOnce.shown) warnOnce.shown = {};
  331. if (!warnOnce.shown[text]) {
  332. warnOnce.shown[text] = 1;
  333. err(text);
  334. }
  335. }
  336.  
  337.  
  338.  
  339.  
  340.  
  341. /**
  342. * @license
  343. * Copyright 2020 The Emscripten Authors
  344. * SPDX-License-Identifier: MIT
  345. */
  346.  
  347.  
  348. // Wraps a JS function as a wasm function with a given signature.
  349. function convertJsFunctionToWasm(func, sig) {
  350.  
  351. // If the type reflection proposal is available, use the new
  352. // "WebAssembly.Function" constructor.
  353. // Otherwise, construct a minimal wasm module importing the JS function and
  354. // re-exporting it.
  355. if (typeof WebAssembly.Function === "function") {
  356. var typeNames = {
  357. 'i': 'i32',
  358. 'j': 'i64',
  359. 'f': 'f32',
  360. 'd': 'f64'
  361. };
  362. var type = {
  363. parameters: [],
  364. results: sig[0] == 'v' ? [] : [typeNames[sig[0]]]
  365. };
  366. for (var i = 1; i < sig.length; ++i) {
  367. type.parameters.push(typeNames[sig[i]]);
  368. }
  369. return new WebAssembly.Function(type, func);
  370. }
  371.  
  372. // The module is static, with the exception of the type section, which is
  373. // generated based on the signature passed in.
  374. var typeSection = [
  375. 0x01, // id: section,
  376. 0x00, // length: 0 (placeholder)
  377. 0x01, // count: 1
  378. 0x60, // form: func
  379. ];
  380. var sigRet = sig.slice(0, 1);
  381. var sigParam = sig.slice(1);
  382. var typeCodes = {
  383. 'i': 0x7f, // i32
  384. 'j': 0x7e, // i64
  385. 'f': 0x7d, // f32
  386. 'd': 0x7c, // f64
  387. };
  388.  
  389. // Parameters, length + signatures
  390. typeSection.push(sigParam.length);
  391. for (var i = 0; i < sigParam.length; ++i) {
  392. typeSection.push(typeCodes[sigParam[i]]);
  393. }
  394.  
  395. // Return values, length + signatures
  396. // With no multi-return in MVP, either 0 (void) or 1 (anything else)
  397. if (sigRet == 'v') {
  398. typeSection.push(0x00);
  399. } else {
  400. typeSection = typeSection.concat([0x01, typeCodes[sigRet]]);
  401. }
  402.  
  403. // Write the overall length of the type section back into the section header
  404. // (excepting the 2 bytes for the section id and length)
  405. typeSection[1] = typeSection.length - 2;
  406.  
  407. // Rest of the module is static
  408. var bytes = new Uint8Array([
  409. 0x00, 0x61, 0x73, 0x6d, // magic ("\0asm")
  410. 0x01, 0x00, 0x00, 0x00, // version: 1
  411. ].concat(typeSection, [
  412. 0x02, 0x07, // import section
  413. // (import "e" "f" (func 0 (type 0)))
  414. 0x01, 0x01, 0x65, 0x01, 0x66, 0x00, 0x00,
  415. 0x07, 0x05, // export section
  416. // (export "f" (func 0 (type 0)))
  417. 0x01, 0x01, 0x66, 0x00, 0x00,
  418. ]));
  419.  
  420. // We can compile this wasm module synchronously because it is very small.
  421. // This accepts an import (at "e.f"), that it reroutes to an export (at "f")
  422. var module = new WebAssembly.Module(bytes);
  423. var instance = new WebAssembly.Instance(module, {
  424. 'e': {
  425. 'f': func
  426. }
  427. });
  428. var wrappedFunc = instance.exports['f'];
  429. return wrappedFunc;
  430. }
  431.  
  432. var freeTableIndexes = [];
  433.  
  434. // Weak map of functions in the table to their indexes, created on first use.
  435. var functionsInTableMap;
  436.  
  437. // Add a wasm function to the table.
  438. function addFunctionWasm(func, sig) {
  439. var table = wasmTable;
  440.  
  441. // Check if the function is already in the table, to ensure each function
  442. // gets a unique index. First, create the map if this is the first use.
  443. if (!functionsInTableMap) {
  444. functionsInTableMap = new WeakMap();
  445. for (var i = 0; i < table.length; i++) {
  446. var item = table.get(i);
  447. // Ignore null values.
  448. if (item) {
  449. functionsInTableMap.set(item, i);
  450. }
  451. }
  452. }
  453. if (functionsInTableMap.has(func)) {
  454. return functionsInTableMap.get(func);
  455. }
  456.  
  457. // It's not in the table, add it now.
  458.  
  459.  
  460. var ret;
  461. // Reuse a free index if there is one, otherwise grow.
  462. if (freeTableIndexes.length) {
  463. ret = freeTableIndexes.pop();
  464. } else {
  465. ret = table.length;
  466. // Grow the table
  467. try {
  468. table.grow(1);
  469. } catch (err) {
  470. if (!(err instanceof RangeError)) {
  471. throw err;
  472. }
  473. throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.';
  474. }
  475. }
  476.  
  477. // Set the new value.
  478. try {
  479. // Attempting to call this with JS function will cause of table.set() to fail
  480. table.set(ret, func);
  481. } catch (err) {
  482. if (!(err instanceof TypeError)) {
  483. throw err;
  484. }
  485. var wrapped = convertJsFunctionToWasm(func, sig);
  486. table.set(ret, wrapped);
  487. }
  488.  
  489. functionsInTableMap.set(func, ret);
  490.  
  491. return ret;
  492. }
  493.  
  494. function removeFunctionWasm(index) {
  495. functionsInTableMap.delete(wasmTable.get(index));
  496. freeTableIndexes.push(index);
  497. }
  498.  
  499. // 'sig' parameter is required for the llvm backend but only when func is not
  500. // already a WebAssembly function.
  501. function addFunction(func, sig) {
  502.  
  503. return addFunctionWasm(func, sig);
  504. }
  505.  
  506. function removeFunction(index) {
  507. removeFunctionWasm(index);
  508. }
  509.  
  510.  
  511.  
  512. var funcWrappers = {};
  513.  
  514. function getFuncWrapper(func, sig) {
  515. if (!func) return; // on null pointer, return undefined
  516. assert(sig);
  517. if (!funcWrappers[sig]) {
  518. funcWrappers[sig] = {};
  519. }
  520. var sigCache = funcWrappers[sig];
  521. if (!sigCache[func]) {
  522. // optimize away arguments usage in common cases
  523. if (sig.length === 1) {
  524. sigCache[func] = function dynCall_wrapper() {
  525. return dynCall(sig, func);
  526. };
  527. } else if (sig.length === 2) {
  528. sigCache[func] = function dynCall_wrapper(arg) {
  529. return dynCall(sig, func, [arg]);
  530. };
  531. } else {
  532. // general case
  533. sigCache[func] = function dynCall_wrapper() {
  534. return dynCall(sig, func, Array.prototype.slice.call(arguments));
  535. };
  536. }
  537. }
  538. return sigCache[func];
  539. }
  540.  
  541.  
  542. /**
  543. * @license
  544. * Copyright 2020 The Emscripten Authors
  545. * SPDX-License-Identifier: MIT
  546. */
  547.  
  548.  
  549.  
  550.  
  551. function makeBigInt(low, high, unsigned) {
  552. return unsigned ? ((+((low>>>0)))+((+((high>>>0)))*4294967296.0)) : ((+((low>>>0)))+((+((high|0)))*4294967296.0));
  553. }
  554.  
  555. /** @param {Array=} args */
  556. function dynCall(sig, ptr, args) {
  557. if (args && args.length) {
  558. return Module['dynCall_' + sig].apply(null, [ptr].concat(args));
  559. } else {
  560. return Module['dynCall_' + sig].call(null, ptr);
  561. }
  562. }
  563.  
  564. var tempRet0 = 0;
  565.  
  566. var setTempRet0 = function(value) {
  567. tempRet0 = value;
  568. };
  569.  
  570. var getTempRet0 = function() {
  571. return tempRet0;
  572. };
  573.  
  574.  
  575. // The address globals begin at. Very low in memory, for code size and optimization opportunities.
  576. // Above 0 is static memory, starting with globals.
  577. // Then the stack.
  578. // Then 'dynamic' memory for sbrk.
  579. var GLOBAL_BASE = 1024;
  580.  
  581.  
  582.  
  583. /**
  584. * @license
  585. * Copyright 2010 The Emscripten Authors
  586. * SPDX-License-Identifier: MIT
  587. */
  588.  
  589. // === Preamble library stuff ===
  590.  
  591. // Documentation for the public APIs defined in this file must be updated in:
  592. // site/source/docs/api_reference/preamble.js.rst
  593. // A prebuilt local version of the documentation is available at:
  594. // site/build/text/docs/api_reference/preamble.js.txt
  595. // You can also build docs locally as HTML or other formats in site/
  596. // An online HTML version (which may be of a different version of Emscripten)
  597. // is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
  598.  
  599.  
  600. var wasmBinary;if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];
  601. var noExitRuntime;if (Module['noExitRuntime']) noExitRuntime = Module['noExitRuntime'];
  602.  
  603.  
  604. if (typeof WebAssembly !== 'object') {
  605. err('no native wasm support detected');
  606. }
  607.  
  608.  
  609. /**
  610. * @license
  611. * Copyright 2019 The Emscripten Authors
  612. * SPDX-License-Identifier: MIT
  613. */
  614.  
  615. // In MINIMAL_RUNTIME, setValue() and getValue() are only available when building with safe heap enabled, for heap safety checking.
  616. // In traditional runtime, setValue() and getValue() are always available (although their use is highly discouraged due to perf penalties)
  617.  
  618. /** @param {number} ptr
  619. @param {number} value
  620. @param {string} type
  621. @param {number|boolean=} noSafe */
  622. function setValue(ptr, value, type, noSafe) {
  623. type = type || 'i8';
  624. if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
  625. switch(type) {
  626. case 'i1': HEAP8[((ptr)>>0)]=value; break;
  627. case 'i8': HEAP8[((ptr)>>0)]=value; break;
  628. case 'i16': HEAP16[((ptr)>>1)]=value; break;
  629. case 'i32': HEAP32[((ptr)>>2)]=value; break;
  630. 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;
  631. case 'float': HEAPF32[((ptr)>>2)]=value; break;
  632. case 'double': HEAPF64[((ptr)>>3)]=value; break;
  633. default: abort('invalid type for setValue: ' + type);
  634. }
  635. }
  636.  
  637. /** @param {number} ptr
  638. @param {string} type
  639. @param {number|boolean=} noSafe */
  640. function getValue(ptr, type, noSafe) {
  641. type = type || 'i8';
  642. if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
  643. switch(type) {
  644. case 'i1': return HEAP8[((ptr)>>0)];
  645. case 'i8': return HEAP8[((ptr)>>0)];
  646. case 'i16': return HEAP16[((ptr)>>1)];
  647. case 'i32': return HEAP32[((ptr)>>2)];
  648. case 'i64': return HEAP32[((ptr)>>2)];
  649. case 'float': return HEAPF32[((ptr)>>2)];
  650. case 'double': return HEAPF64[((ptr)>>3)];
  651. default: abort('invalid type for getValue: ' + type);
  652. }
  653. return null;
  654. }
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661. // Wasm globals
  662.  
  663. var wasmMemory;
  664.  
  665. // In fastcomp asm.js, we don't need a wasm Table at all.
  666. // In the wasm backend, we polyfill the WebAssembly object,
  667. // so this creates a (non-native-wasm) table for us.
  668. var wasmTable = new WebAssembly.Table({
  669. 'initial': 722,
  670. 'maximum': 722 + 0,
  671. 'element': 'anyfunc'
  672. });
  673.  
  674.  
  675. //========================================
  676. // Runtime essentials
  677. //========================================
  678.  
  679. // whether we are quitting the application. no code should run after this.
  680. // set in exit() and abort()
  681. var ABORT = false;
  682.  
  683. // set by exit() and abort(). Passed to 'onExit' handler.
  684. // NOTE: This is also used as the process return code code in shell environments
  685. // but only when noExitRuntime is false.
  686. var EXITSTATUS = 0;
  687.  
  688. /** @type {function(*, string=)} */
  689. function assert(condition, text) {
  690. if (!condition) {
  691. abort('Assertion failed: ' + text);
  692. }
  693. }
  694.  
  695. // Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
  696. function getCFunc(ident) {
  697. var func = Module['_' + ident]; // closure exported function
  698. assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported');
  699. return func;
  700. }
  701.  
  702. // C calling interface.
  703. /** @param {string|null=} returnType
  704. @param {Array=} argTypes
  705. @param {Arguments|Array=} args
  706. @param {Object=} opts */
  707. function ccall(ident, returnType, argTypes, args, opts) {
  708. // For fast lookup of conversion functions
  709. var toC = {
  710. 'string': function(str) {
  711. var ret = 0;
  712. if (str !== null && str !== undefined && str !== 0) { // null string
  713. // at most 4 bytes per UTF-8 code point, +1 for the trailing '\0'
  714. var len = (str.length << 2) + 1;
  715. ret = stackAlloc(len);
  716. stringToUTF8(str, ret, len);
  717. }
  718. return ret;
  719. },
  720. 'array': function(arr) {
  721. var ret = stackAlloc(arr.length);
  722. writeArrayToMemory(arr, ret);
  723. return ret;
  724. }
  725. };
  726.  
  727. function convertReturnValue(ret) {
  728. if (returnType === 'string') return UTF8ToString(ret);
  729. if (returnType === 'boolean') return Boolean(ret);
  730. return ret;
  731. }
  732.  
  733. var func = getCFunc(ident);
  734. var cArgs = [];
  735. var stack = 0;
  736. if (args) {
  737. for (var i = 0; i < args.length; i++) {
  738. var converter = toC[argTypes[i]];
  739. if (converter) {
  740. if (stack === 0) stack = stackSave();
  741. cArgs[i] = converter(args[i]);
  742. } else {
  743. cArgs[i] = args[i];
  744. }
  745. }
  746. }
  747. var ret = func.apply(null, cArgs);
  748.  
  749. ret = convertReturnValue(ret);
  750. if (stack !== 0) stackRestore(stack);
  751. return ret;
  752. }
  753.  
  754. /** @param {string=} returnType
  755. @param {Array=} argTypes
  756. @param {Object=} opts */
  757. function cwrap(ident, returnType, argTypes, opts) {
  758. argTypes = argTypes || [];
  759. // When the function takes numbers and returns a number, we can just return
  760. // the original function
  761. var numericArgs = argTypes.every(function(type){ return type === 'number'});
  762. var numericRet = returnType !== 'string';
  763. if (numericRet && numericArgs && !opts) {
  764. return getCFunc(ident);
  765. }
  766. return function() {
  767. return ccall(ident, returnType, argTypes, arguments, opts);
  768. }
  769. }
  770.  
  771. var ALLOC_NORMAL = 0; // Tries to use _malloc()
  772. var ALLOC_STACK = 1; // Lives for the duration of the current function call
  773. var ALLOC_DYNAMIC = 2; // Cannot be freed except through sbrk
  774. var ALLOC_NONE = 3; // Do not allocate
  775.  
  776. // allocate(): This is for internal use. You can use it yourself as well, but the interface
  777. // is a little tricky (see docs right below). The reason is that it is optimized
  778. // for multiple syntaxes to save space in generated code. So you should
  779. // normally not use allocate(), and instead allocate memory using _malloc(),
  780. // initialize it with setValue(), and so forth.
  781. // @slab: An array of data, or a number. If a number, then the size of the block to allocate,
  782. // in *bytes* (note that this is sometimes confusing: the next parameter does not
  783. // affect this!)
  784. // @types: Either an array of types, one for each byte (or 0 if no type at that position),
  785. // or a single type which is used for the entire block. This only matters if there
  786. // is initial data - if @slab is a number, then this does not matter at all and is
  787. // ignored.
  788. // @allocator: How to allocate memory, see ALLOC_*
  789. /** @type {function((TypedArray|Array<number>|number), string, number, number=)} */
  790. function allocate(slab, types, allocator, ptr) {
  791. var zeroinit, size;
  792. if (typeof slab === 'number') {
  793. zeroinit = true;
  794. size = slab;
  795. } else {
  796. zeroinit = false;
  797. size = slab.length;
  798. }
  799.  
  800. var singleType = typeof types === 'string' ? types : null;
  801.  
  802. var ret;
  803. if (allocator == ALLOC_NONE) {
  804. ret = ptr;
  805. } else {
  806. ret = [_malloc,
  807. stackAlloc,
  808. dynamicAlloc][allocator](Math.max(size, singleType ? 1 : types.length));
  809. }
  810.  
  811. if (zeroinit) {
  812. var stop;
  813. ptr = ret;
  814. assert((ret & 3) == 0);
  815. stop = ret + (size & ~3);
  816. for (; ptr < stop; ptr += 4) {
  817. HEAP32[((ptr)>>2)]=0;
  818. }
  819. stop = ret + size;
  820. while (ptr < stop) {
  821. HEAP8[((ptr++)>>0)]=0;
  822. }
  823. return ret;
  824. }
  825.  
  826. if (singleType === 'i8') {
  827. if (slab.subarray || slab.slice) {
  828. HEAPU8.set(/** @type {!Uint8Array} */ (slab), ret);
  829. } else {
  830. HEAPU8.set(new Uint8Array(slab), ret);
  831. }
  832. return ret;
  833. }
  834.  
  835. var i = 0, type, typeSize, previousType;
  836. while (i < size) {
  837. var curr = slab[i];
  838.  
  839. type = singleType || types[i];
  840. if (type === 0) {
  841. i++;
  842. continue;
  843. }
  844.  
  845. if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later
  846.  
  847. setValue(ret+i, curr, type);
  848.  
  849. // no need to look up size unless type changes, so cache it
  850. if (previousType !== type) {
  851. typeSize = getNativeTypeSize(type);
  852. previousType = type;
  853. }
  854. i += typeSize;
  855. }
  856.  
  857. return ret;
  858. }
  859.  
  860. // Allocate memory during any stage of startup - static memory early on, dynamic memory later, malloc when ready
  861. function getMemory(size) {
  862. if (!runtimeInitialized) return dynamicAlloc(size);
  863. return _malloc(size);
  864. }
  865.  
  866.  
  867. /**
  868. * @license
  869. * Copyright 2019 The Emscripten Authors
  870. * SPDX-License-Identifier: MIT
  871. */
  872.  
  873. // runtime_strings.js: Strings related runtime functions that are part of both MINIMAL_RUNTIME and regular runtime.
  874.  
  875. // Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the given array that contains uint8 values, returns
  876. // a copy of that string as a Javascript String object.
  877.  
  878. var UTF8Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf8') : undefined;
  879.  
  880. /**
  881. * @param {number} idx
  882. * @param {number=} maxBytesToRead
  883. * @return {string}
  884. */
  885. function UTF8ArrayToString(heap, idx, maxBytesToRead) {
  886. var endIdx = idx + maxBytesToRead;
  887. var endPtr = idx;
  888. // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.
  889. // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.
  890. // (As a tiny code save trick, compare endPtr against endIdx using a negation, so that undefined means Infinity)
  891. while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr;
  892.  
  893. if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) {
  894. return UTF8Decoder.decode(heap.subarray(idx, endPtr));
  895. } else {
  896. var str = '';
  897. // If building with TextDecoder, we have already computed the string length above, so test loop end condition against that
  898. while (idx < endPtr) {
  899. // For UTF8 byte structure, see:
  900. // http://en.wikipedia.org/wiki/UTF-8#Description
  901. // https://www.ietf.org/rfc/rfc2279.txt
  902. // https://tools.ietf.org/html/rfc3629
  903. var u0 = heap[idx++];
  904. if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }
  905. var u1 = heap[idx++] & 63;
  906. if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }
  907. var u2 = heap[idx++] & 63;
  908. if ((u0 & 0xF0) == 0xE0) {
  909. u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
  910. } else {
  911. u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heap[idx++] & 63);
  912. }
  913.  
  914. if (u0 < 0x10000) {
  915. str += String.fromCharCode(u0);
  916. } else {
  917. var ch = u0 - 0x10000;
  918. str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
  919. }
  920. }
  921. }
  922. return str;
  923. }
  924.  
  925. // Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the emscripten HEAP, returns a
  926. // copy of that string as a Javascript String object.
  927. // maxBytesToRead: an optional length that specifies the maximum number of bytes to read. You can omit
  928. // this parameter to scan the string until the first \0 byte. If maxBytesToRead is
  929. // passed, and the string at [ptr, ptr+maxBytesToReadr[ contains a null byte in the
  930. // middle, then the string will cut short at that byte index (i.e. maxBytesToRead will
  931. // not produce a string of exact length [ptr, ptr+maxBytesToRead[)
  932. // N.B. mixing frequent uses of UTF8ToString() with and without maxBytesToRead may
  933. // throw JS JIT optimizations off, so it is worth to consider consistently using one
  934. // style or the other.
  935. /**
  936. * @param {number} ptr
  937. * @param {number=} maxBytesToRead
  938. * @return {string}
  939. */
  940. function UTF8ToString(ptr, maxBytesToRead) {
  941. return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';
  942. }
  943.  
  944. // Copies the given Javascript String object 'str' to the given byte array at address 'outIdx',
  945. // encoded in UTF8 form and null-terminated. The copy will require at most str.length*4+1 bytes of space in the HEAP.
  946. // Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.
  947. // Parameters:
  948. // str: the Javascript string to copy.
  949. // heap: the array to copy to. Each index in this array is assumed to be one 8-byte element.
  950. // outIdx: The starting offset in the array to begin the copying.
  951. // maxBytesToWrite: The maximum number of bytes this function can write to the array.
  952. // This count should include the null terminator,
  953. // i.e. if maxBytesToWrite=1, only the null terminator will be written and nothing else.
  954. // maxBytesToWrite=0 does not write any bytes to the output, not even the null terminator.
  955. // Returns the number of bytes written, EXCLUDING the null terminator.
  956.  
  957. function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
  958. if (!(maxBytesToWrite > 0)) // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes.
  959. return 0;
  960.  
  961. var startIdx = outIdx;
  962. var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.
  963. for (var i = 0; i < str.length; ++i) {
  964. // 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.
  965. // See http://unicode.org/faq/utf_bom.html#utf16-3
  966. // 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
  967. var u = str.charCodeAt(i); // possibly a lead surrogate
  968. if (u >= 0xD800 && u <= 0xDFFF) {
  969. var u1 = str.charCodeAt(++i);
  970. u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF);
  971. }
  972. if (u <= 0x7F) {
  973. if (outIdx >= endIdx) break;
  974. heap[outIdx++] = u;
  975. } else if (u <= 0x7FF) {
  976. if (outIdx + 1 >= endIdx) break;
  977. heap[outIdx++] = 0xC0 | (u >> 6);
  978. heap[outIdx++] = 0x80 | (u & 63);
  979. } else if (u <= 0xFFFF) {
  980. if (outIdx + 2 >= endIdx) break;
  981. heap[outIdx++] = 0xE0 | (u >> 12);
  982. heap[outIdx++] = 0x80 | ((u >> 6) & 63);
  983. heap[outIdx++] = 0x80 | (u & 63);
  984. } else {
  985. if (outIdx + 3 >= endIdx) break;
  986. heap[outIdx++] = 0xF0 | (u >> 18);
  987. heap[outIdx++] = 0x80 | ((u >> 12) & 63);
  988. heap[outIdx++] = 0x80 | ((u >> 6) & 63);
  989. heap[outIdx++] = 0x80 | (u & 63);
  990. }
  991. }
  992. // Null-terminate the pointer to the buffer.
  993. heap[outIdx] = 0;
  994. return outIdx - startIdx;
  995. }
  996.  
  997. // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
  998. // null-terminated and encoded in UTF8 form. The copy will require at most str.length*4+1 bytes of space in the HEAP.
  999. // Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.
  1000. // Returns the number of bytes written, EXCLUDING the null terminator.
  1001.  
  1002. function stringToUTF8(str, outPtr, maxBytesToWrite) {
  1003. return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite);
  1004. }
  1005.  
  1006. // Returns the number of bytes the given Javascript string takes if encoded as a UTF8 byte array, EXCLUDING the null terminator byte.
  1007. function lengthBytesUTF8(str) {
  1008. var len = 0;
  1009. for (var i = 0; i < str.length; ++i) {
  1010. // 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.
  1011. // See http://unicode.org/faq/utf_bom.html#utf16-3
  1012. var u = str.charCodeAt(i); // possibly a lead surrogate
  1013. if (u >= 0xD800 && u <= 0xDFFF) u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF);
  1014. if (u <= 0x7F) ++len;
  1015. else if (u <= 0x7FF) len += 2;
  1016. else if (u <= 0xFFFF) len += 3;
  1017. else len += 4;
  1018. }
  1019. return len;
  1020. }
  1021.  
  1022.  
  1023.  
  1024. /**
  1025. * @license
  1026. * Copyright 2020 The Emscripten Authors
  1027. * SPDX-License-Identifier: MIT
  1028. */
  1029.  
  1030. // runtime_strings_extra.js: Strings related runtime functions that are available only in regular runtime.
  1031.  
  1032. // Given a pointer 'ptr' to a null-terminated ASCII-encoded string in the emscripten HEAP, returns
  1033. // a copy of that string as a Javascript String object.
  1034.  
  1035. function AsciiToString(ptr) {
  1036. var str = '';
  1037. while (1) {
  1038. var ch = HEAPU8[((ptr++)>>0)];
  1039. if (!ch) return str;
  1040. str += String.fromCharCode(ch);
  1041. }
  1042. }
  1043.  
  1044. // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
  1045. // null-terminated and encoded in ASCII form. The copy will require at most str.length+1 bytes of space in the HEAP.
  1046.  
  1047. function stringToAscii(str, outPtr) {
  1048. return writeAsciiToMemory(str, outPtr, false);
  1049. }
  1050.  
  1051. // Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
  1052. // a copy of that string as a Javascript String object.
  1053.  
  1054. var UTF16Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-16le') : undefined;
  1055.  
  1056. function UTF16ToString(ptr, maxBytesToRead) {
  1057. var endPtr = ptr;
  1058. // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.
  1059. // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.
  1060. var idx = endPtr >> 1;
  1061. var maxIdx = idx + maxBytesToRead / 2;
  1062. // If maxBytesToRead is not passed explicitly, it will be undefined, and this
  1063. // will always evaluate to true. This saves on code size.
  1064. while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx;
  1065. endPtr = idx << 1;
  1066.  
  1067. if (endPtr - ptr > 32 && UTF16Decoder) {
  1068. return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr));
  1069. } else {
  1070. var i = 0;
  1071.  
  1072. var str = '';
  1073. while (1) {
  1074. var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
  1075. if (codeUnit == 0 || i == maxBytesToRead / 2) return str;
  1076. ++i;
  1077. // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
  1078. str += String.fromCharCode(codeUnit);
  1079. }
  1080. }
  1081. }
  1082.  
  1083. // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
  1084. // null-terminated and encoded in UTF16 form. The copy will require at most str.length*4+2 bytes of space in the HEAP.
  1085. // Use the function lengthBytesUTF16() to compute the exact number of bytes (excluding null terminator) that this function will write.
  1086. // Parameters:
  1087. // str: the Javascript string to copy.
  1088. // outPtr: Byte address in Emscripten HEAP where to write the string to.
  1089. // maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
  1090. // terminator, i.e. if maxBytesToWrite=2, only the null terminator will be written and nothing else.
  1091. // maxBytesToWrite<2 does not write any bytes to the output, not even the null terminator.
  1092. // Returns the number of bytes written, EXCLUDING the null terminator.
  1093.  
  1094. function stringToUTF16(str, outPtr, maxBytesToWrite) {
  1095. // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
  1096. if (maxBytesToWrite === undefined) {
  1097. maxBytesToWrite = 0x7FFFFFFF;
  1098. }
  1099. if (maxBytesToWrite < 2) return 0;
  1100. maxBytesToWrite -= 2; // Null terminator.
  1101. var startPtr = outPtr;
  1102. var numCharsToWrite = (maxBytesToWrite < str.length*2) ? (maxBytesToWrite / 2) : str.length;
  1103. for (var i = 0; i < numCharsToWrite; ++i) {
  1104. // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
  1105. var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
  1106. HEAP16[((outPtr)>>1)]=codeUnit;
  1107. outPtr += 2;
  1108. }
  1109. // Null-terminate the pointer to the HEAP.
  1110. HEAP16[((outPtr)>>1)]=0;
  1111. return outPtr - startPtr;
  1112. }
  1113.  
  1114. // Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.
  1115.  
  1116. function lengthBytesUTF16(str) {
  1117. return str.length*2;
  1118. }
  1119.  
  1120. function UTF32ToString(ptr, maxBytesToRead) {
  1121. var i = 0;
  1122.  
  1123. var str = '';
  1124. // If maxBytesToRead is not passed explicitly, it will be undefined, and this
  1125. // will always evaluate to true. This saves on code size.
  1126. while (!(i >= maxBytesToRead / 4)) {
  1127. var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
  1128. if (utf32 == 0) break;
  1129. ++i;
  1130. // 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.
  1131. // See http://unicode.org/faq/utf_bom.html#utf16-3
  1132. if (utf32 >= 0x10000) {
  1133. var ch = utf32 - 0x10000;
  1134. str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
  1135. } else {
  1136. str += String.fromCharCode(utf32);
  1137. }
  1138. }
  1139. return str;
  1140. }
  1141.  
  1142. // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
  1143. // null-terminated and encoded in UTF32 form. The copy will require at most str.length*4+4 bytes of space in the HEAP.
  1144. // Use the function lengthBytesUTF32() to compute the exact number of bytes (excluding null terminator) that this function will write.
  1145. // Parameters:
  1146. // str: the Javascript string to copy.
  1147. // outPtr: Byte address in Emscripten HEAP where to write the string to.
  1148. // maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
  1149. // terminator, i.e. if maxBytesToWrite=4, only the null terminator will be written and nothing else.
  1150. // maxBytesToWrite<4 does not write any bytes to the output, not even the null terminator.
  1151. // Returns the number of bytes written, EXCLUDING the null terminator.
  1152.  
  1153. function stringToUTF32(str, outPtr, maxBytesToWrite) {
  1154. // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
  1155. if (maxBytesToWrite === undefined) {
  1156. maxBytesToWrite = 0x7FFFFFFF;
  1157. }
  1158. if (maxBytesToWrite < 4) return 0;
  1159. var startPtr = outPtr;
  1160. var endPtr = startPtr + maxBytesToWrite - 4;
  1161. for (var i = 0; i < str.length; ++i) {
  1162. // 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.
  1163. // See http://unicode.org/faq/utf_bom.html#utf16-3
  1164. var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
  1165. if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
  1166. var trailSurrogate = str.charCodeAt(++i);
  1167. codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
  1168. }
  1169. HEAP32[((outPtr)>>2)]=codeUnit;
  1170. outPtr += 4;
  1171. if (outPtr + 4 > endPtr) break;
  1172. }
  1173. // Null-terminate the pointer to the HEAP.
  1174. HEAP32[((outPtr)>>2)]=0;
  1175. return outPtr - startPtr;
  1176. }
  1177.  
  1178. // Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.
  1179.  
  1180. function lengthBytesUTF32(str) {
  1181. var len = 0;
  1182. for (var i = 0; i < str.length; ++i) {
  1183. // 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.
  1184. // See http://unicode.org/faq/utf_bom.html#utf16-3
  1185. var codeUnit = str.charCodeAt(i);
  1186. if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) ++i; // possibly a lead surrogate, so skip over the tail surrogate.
  1187. len += 4;
  1188. }
  1189.  
  1190. return len;
  1191. }
  1192.  
  1193. // Allocate heap space for a JS string, and write it there.
  1194. // It is the responsibility of the caller to free() that memory.
  1195. function allocateUTF8(str) {
  1196. var size = lengthBytesUTF8(str) + 1;
  1197. var ret = _malloc(size);
  1198. if (ret) stringToUTF8Array(str, HEAP8, ret, size);
  1199. return ret;
  1200. }
  1201.  
  1202. // Allocate stack space for a JS string, and write it there.
  1203. function allocateUTF8OnStack(str) {
  1204. var size = lengthBytesUTF8(str) + 1;
  1205. var ret = stackAlloc(size);
  1206. stringToUTF8Array(str, HEAP8, ret, size);
  1207. return ret;
  1208. }
  1209.  
  1210. // Deprecated: This function should not be called because it is unsafe and does not provide
  1211. // a maximum length limit of how many bytes it is allowed to write. Prefer calling the
  1212. // function stringToUTF8Array() instead, which takes in a maximum length that can be used
  1213. // to be secure from out of bounds writes.
  1214. /** @deprecated
  1215. @param {boolean=} dontAddNull */
  1216. function writeStringToMemory(string, buffer, dontAddNull) {
  1217. warnOnce('writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!');
  1218.  
  1219. var /** @type {number} */ lastChar, /** @type {number} */ end;
  1220. if (dontAddNull) {
  1221. // stringToUTF8Array always appends null. If we don't want to do that, remember the
  1222. // character that existed at the location where the null will be placed, and restore
  1223. // that after the write (below).
  1224. end = buffer + lengthBytesUTF8(string);
  1225. lastChar = HEAP8[end];
  1226. }
  1227. stringToUTF8(string, buffer, Infinity);
  1228. if (dontAddNull) HEAP8[end] = lastChar; // Restore the value under the null character.
  1229. }
  1230.  
  1231. function writeArrayToMemory(array, buffer) {
  1232. HEAP8.set(array, buffer);
  1233. }
  1234.  
  1235. /** @param {boolean=} dontAddNull */
  1236. function writeAsciiToMemory(str, buffer, dontAddNull) {
  1237. for (var i = 0; i < str.length; ++i) {
  1238. HEAP8[((buffer++)>>0)]=str.charCodeAt(i);
  1239. }
  1240. // Null-terminate the pointer to the HEAP.
  1241. if (!dontAddNull) HEAP8[((buffer)>>0)]=0;
  1242. }
  1243.  
  1244.  
  1245.  
  1246. // Memory management
  1247.  
  1248. var PAGE_SIZE = 16384;
  1249. var WASM_PAGE_SIZE = 65536;
  1250. var ASMJS_PAGE_SIZE = 16777216;
  1251.  
  1252. function alignUp(x, multiple) {
  1253. if (x % multiple > 0) {
  1254. x += multiple - (x % multiple);
  1255. }
  1256. return x;
  1257. }
  1258.  
  1259. var HEAP,
  1260. /** @type {ArrayBuffer} */
  1261. buffer,
  1262. /** @type {Int8Array} */
  1263. HEAP8,
  1264. /** @type {Uint8Array} */
  1265. HEAPU8,
  1266. /** @type {Int16Array} */
  1267. HEAP16,
  1268. /** @type {Uint16Array} */
  1269. HEAPU16,
  1270. /** @type {Int32Array} */
  1271. HEAP32,
  1272. /** @type {Uint32Array} */
  1273. HEAPU32,
  1274. /** @type {Float32Array} */
  1275. HEAPF32,
  1276. /** @type {Float64Array} */
  1277. HEAPF64;
  1278.  
  1279. function updateGlobalBufferAndViews(buf) {
  1280. buffer = buf;
  1281. Module['HEAP8'] = HEAP8 = new Int8Array(buf);
  1282. Module['HEAP16'] = HEAP16 = new Int16Array(buf);
  1283. Module['HEAP32'] = HEAP32 = new Int32Array(buf);
  1284. Module['HEAPU8'] = HEAPU8 = new Uint8Array(buf);
  1285. Module['HEAPU16'] = HEAPU16 = new Uint16Array(buf);
  1286. Module['HEAPU32'] = HEAPU32 = new Uint32Array(buf);
  1287. Module['HEAPF32'] = HEAPF32 = new Float32Array(buf);
  1288. Module['HEAPF64'] = HEAPF64 = new Float64Array(buf);
  1289. }
  1290.  
  1291. var STATIC_BASE = 1024,
  1292. STACK_BASE = 6220672,
  1293. STACKTOP = STACK_BASE,
  1294. STACK_MAX = 977792,
  1295. DYNAMIC_BASE = 6220672,
  1296. DYNAMICTOP_PTR = 977632;
  1297.  
  1298.  
  1299.  
  1300.  
  1301. var TOTAL_STACK = 5242880;
  1302.  
  1303. var INITIAL_INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 16777216;
  1304.  
  1305.  
  1306.  
  1307.  
  1308. /**
  1309. * @license
  1310. * Copyright 2019 The Emscripten Authors
  1311. * SPDX-License-Identifier: MIT
  1312. */
  1313.  
  1314.  
  1315.  
  1316.  
  1317. // In standalone mode, the wasm creates the memory, and the user can't provide it.
  1318. // In non-standalone/normal mode, we create the memory here.
  1319.  
  1320. /**
  1321. * @license
  1322. * Copyright 2019 The Emscripten Authors
  1323. * SPDX-License-Identifier: MIT
  1324. */
  1325.  
  1326. // Create the main memory. (Note: this isn't used in STANDALONE_WASM mode since the wasm
  1327. // memory is created in the wasm, not in JS.)
  1328.  
  1329. if (Module['wasmMemory']) {
  1330. wasmMemory = Module['wasmMemory'];
  1331. } else
  1332. {
  1333. wasmMemory = new WebAssembly.Memory({
  1334. 'initial': INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE
  1335. ,
  1336. 'maximum': INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE
  1337. });
  1338. }
  1339.  
  1340.  
  1341. if (wasmMemory) {
  1342. buffer = wasmMemory.buffer;
  1343. }
  1344.  
  1345. // If the user provides an incorrect length, just use that length instead rather than providing the user to
  1346. // specifically provide the memory length with Module['INITIAL_MEMORY'].
  1347. INITIAL_INITIAL_MEMORY = buffer.byteLength;
  1348. updateGlobalBufferAndViews(buffer);
  1349.  
  1350. HEAP32[DYNAMICTOP_PTR>>2] = DYNAMIC_BASE;
  1351.  
  1352.  
  1353.  
  1354.  
  1355. /**
  1356. * @license
  1357. * Copyright 2019 The Emscripten Authors
  1358. * SPDX-License-Identifier: MIT
  1359. */
  1360.  
  1361.  
  1362.  
  1363.  
  1364. /**
  1365. * @license
  1366. * Copyright 2019 The Emscripten Authors
  1367. * SPDX-License-Identifier: MIT
  1368. */
  1369.  
  1370.  
  1371.  
  1372.  
  1373. function callRuntimeCallbacks(callbacks) {
  1374. while(callbacks.length > 0) {
  1375. var callback = callbacks.shift();
  1376. if (typeof callback == 'function') {
  1377. callback(Module); // Pass the module as the first argument.
  1378. continue;
  1379. }
  1380. var func = callback.func;
  1381. if (typeof func === 'number') {
  1382. if (callback.arg === undefined) {
  1383. Module['dynCall_v'](func);
  1384. } else {
  1385. Module['dynCall_vi'](func, callback.arg);
  1386. }
  1387. } else {
  1388. func(callback.arg === undefined ? null : callback.arg);
  1389. }
  1390. }
  1391. }
  1392.  
  1393. var __ATPRERUN__ = []; // functions called before the runtime is initialized
  1394. var __ATINIT__ = []; // functions called during startup
  1395. var __ATMAIN__ = []; // functions called when main() is to be run
  1396. var __ATEXIT__ = []; // functions called during shutdown
  1397. var __ATPOSTRUN__ = []; // functions called after the main() is called
  1398.  
  1399. var runtimeInitialized = false;
  1400. var runtimeExited = false;
  1401.  
  1402.  
  1403. function preRun() {
  1404.  
  1405. if (Module['preRun']) {
  1406. if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
  1407. while (Module['preRun'].length) {
  1408. addOnPreRun(Module['preRun'].shift());
  1409. }
  1410. }
  1411.  
  1412. callRuntimeCallbacks(__ATPRERUN__);
  1413. }
  1414.  
  1415. function initRuntime() {
  1416. runtimeInitialized = true;
  1417. if (!Module["noFSInit"] && !FS.init.initialized) FS.init();
  1418. TTY.init();
  1419. PIPEFS.root = FS.mount(PIPEFS, {}, null);
  1420. SOCKFS.root = FS.mount(SOCKFS, {}, null);
  1421. callRuntimeCallbacks(__ATINIT__);
  1422. }
  1423.  
  1424. function preMain() {
  1425. FS.ignorePermissions = false;
  1426. callRuntimeCallbacks(__ATMAIN__);
  1427. }
  1428.  
  1429. function exitRuntime() {
  1430. runtimeExited = true;
  1431. }
  1432.  
  1433. function postRun() {
  1434.  
  1435. if (Module['postRun']) {
  1436. if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
  1437. while (Module['postRun'].length) {
  1438. addOnPostRun(Module['postRun'].shift());
  1439. }
  1440. }
  1441.  
  1442. callRuntimeCallbacks(__ATPOSTRUN__);
  1443. }
  1444.  
  1445. function addOnPreRun(cb) {
  1446. __ATPRERUN__.unshift(cb);
  1447. }
  1448.  
  1449. function addOnInit(cb) {
  1450. __ATINIT__.unshift(cb);
  1451. }
  1452.  
  1453. function addOnPreMain(cb) {
  1454. __ATMAIN__.unshift(cb);
  1455. }
  1456.  
  1457. function addOnExit(cb) {
  1458. }
  1459.  
  1460. function addOnPostRun(cb) {
  1461. __ATPOSTRUN__.unshift(cb);
  1462. }
  1463.  
  1464. /** @param {number|boolean=} ignore */
  1465. function unSign(value, bits, ignore) {
  1466. if (value >= 0) {
  1467. return value;
  1468. }
  1469. return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
  1470. : Math.pow(2, bits) + value;
  1471. }
  1472. /** @param {number|boolean=} ignore */
  1473. function reSign(value, bits, ignore) {
  1474. if (value <= 0) {
  1475. return value;
  1476. }
  1477. var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
  1478. : Math.pow(2, bits-1);
  1479. if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that
  1480. // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
  1481. // TODO: In i64 mode 1, resign the two parts separately and safely
  1482. value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
  1483. }
  1484. return value;
  1485. }
  1486.  
  1487.  
  1488. /**
  1489. * @license
  1490. * Copyright 2019 The Emscripten Authors
  1491. * SPDX-License-Identifier: MIT
  1492. */
  1493.  
  1494. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
  1495.  
  1496. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
  1497.  
  1498. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
  1499.  
  1500. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc
  1501.  
  1502.  
  1503. var Math_abs = Math.abs;
  1504. var Math_cos = Math.cos;
  1505. var Math_sin = Math.sin;
  1506. var Math_tan = Math.tan;
  1507. var Math_acos = Math.acos;
  1508. var Math_asin = Math.asin;
  1509. var Math_atan = Math.atan;
  1510. var Math_atan2 = Math.atan2;
  1511. var Math_exp = Math.exp;
  1512. var Math_log = Math.log;
  1513. var Math_sqrt = Math.sqrt;
  1514. var Math_ceil = Math.ceil;
  1515. var Math_floor = Math.floor;
  1516. var Math_pow = Math.pow;
  1517. var Math_imul = Math.imul;
  1518. var Math_fround = Math.fround;
  1519. var Math_round = Math.round;
  1520. var Math_min = Math.min;
  1521. var Math_max = Math.max;
  1522. var Math_clz32 = Math.clz32;
  1523. var Math_trunc = Math.trunc;
  1524.  
  1525.  
  1526.  
  1527. // A counter of dependencies for calling run(). If we need to
  1528. // do asynchronous work before running, increment this and
  1529. // decrement it. Incrementing must happen in a place like
  1530. // Module.preRun (used by emcc to add file preloading).
  1531. // Note that you can add dependencies in preRun, even though
  1532. // it happens right before run - run will be postponed until
  1533. // the dependencies are met.
  1534. var runDependencies = 0;
  1535. var runDependencyWatcher = null;
  1536. var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
  1537.  
  1538. function getUniqueRunDependency(id) {
  1539. return id;
  1540. }
  1541.  
  1542. function addRunDependency(id) {
  1543. runDependencies++;
  1544.  
  1545. if (Module['monitorRunDependencies']) {
  1546. Module['monitorRunDependencies'](runDependencies);
  1547. }
  1548.  
  1549. }
  1550.  
  1551. function removeRunDependency(id) {
  1552. runDependencies--;
  1553.  
  1554. if (Module['monitorRunDependencies']) {
  1555. Module['monitorRunDependencies'](runDependencies);
  1556. }
  1557.  
  1558. if (runDependencies == 0) {
  1559. if (runDependencyWatcher !== null) {
  1560. clearInterval(runDependencyWatcher);
  1561. runDependencyWatcher = null;
  1562. }
  1563. if (dependenciesFulfilled) {
  1564. var callback = dependenciesFulfilled;
  1565. dependenciesFulfilled = null;
  1566. callback(); // can add another dependenciesFulfilled
  1567. }
  1568. }
  1569. }
  1570.  
  1571. Module["preloadedImages"] = {}; // maps url to image data
  1572. Module["preloadedAudios"] = {}; // maps url to audio data
  1573.  
  1574.  
  1575. /** @param {string|number=} what */
  1576. function abort(what) {
  1577. if (Module['onAbort']) {
  1578. Module['onAbort'](what);
  1579. }
  1580.  
  1581. what += '';
  1582. out(what);
  1583. err(what);
  1584.  
  1585. ABORT = true;
  1586. EXITSTATUS = 1;
  1587.  
  1588. what = 'abort(' + what + '). Build with -s ASSERTIONS=1 for more info.';
  1589.  
  1590. // Throw a wasm runtime error, because a JS error might be seen as a foreign
  1591. // exception, which means we'd run destructors on it. We need the error to
  1592. // simply make the program stop.
  1593. throw new WebAssembly.RuntimeError(what);
  1594. }
  1595.  
  1596.  
  1597. var memoryInitializer = null;
  1598.  
  1599.  
  1600. /**
  1601. * @license
  1602. * Copyright 2015 The Emscripten Authors
  1603. * SPDX-License-Identifier: MIT
  1604. */
  1605.  
  1606.  
  1607.  
  1608.  
  1609.  
  1610.  
  1611.  
  1612. /**
  1613. * @license
  1614. * Copyright 2017 The Emscripten Authors
  1615. * SPDX-License-Identifier: MIT
  1616. */
  1617.  
  1618. function hasPrefix(str, prefix) {
  1619. return String.prototype.startsWith ?
  1620. str.startsWith(prefix) :
  1621. str.indexOf(prefix) === 0;
  1622. }
  1623.  
  1624. // Prefix of data URIs emitted by SINGLE_FILE and related options.
  1625. var dataURIPrefix = 'data:application/octet-stream;base64,';
  1626.  
  1627. // Indicates whether filename is a base64 data URI.
  1628. function isDataURI(filename) {
  1629. return hasPrefix(filename, dataURIPrefix);
  1630. }
  1631.  
  1632. var fileURIPrefix = "file://";
  1633.  
  1634. // Indicates whether filename is delivered via file protocol (as opposed to http/https)
  1635. function isFileURI(filename) {
  1636. return hasPrefix(filename, fileURIPrefix);
  1637. }
  1638.  
  1639.  
  1640.  
  1641. var wasmBinaryFile = 'pdftex.wasm';
  1642. if (!isDataURI(wasmBinaryFile)) {
  1643. wasmBinaryFile = locateFile(wasmBinaryFile);
  1644. }
  1645.  
  1646. function getBinary() {
  1647. try {
  1648. if (wasmBinary) {
  1649. return new Uint8Array(wasmBinary);
  1650. }
  1651.  
  1652. if (readBinary) {
  1653. return readBinary(wasmBinaryFile);
  1654. } else {
  1655. throw "both async and sync fetching of the wasm failed";
  1656. }
  1657. }
  1658. catch (err) {
  1659. abort(err);
  1660. }
  1661. }
  1662.  
  1663. function getBinaryPromise() {
  1664. // If we don't have the binary yet, and have the Fetch api, use that;
  1665. // in some environments, like Electron's render process, Fetch api may be present, but have a different context than expected, let's only use it on the Web
  1666. if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && typeof fetch === 'function'
  1667. // Let's not use fetch to get objects over file:// as it's most likely Cordova which doesn't support fetch for file://
  1668. && !isFileURI(wasmBinaryFile)
  1669. ) {
  1670. return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) {
  1671. if (!response['ok']) {
  1672. throw "failed to load wasm binary file at '" + wasmBinaryFile + "'";
  1673. }
  1674. return response['arrayBuffer']();
  1675. }).catch(function () {
  1676. return getBinary();
  1677. });
  1678. }
  1679. // Otherwise, getBinary should be able to get it synchronously
  1680. return new Promise(function(resolve, reject) {
  1681. resolve(getBinary());
  1682. });
  1683. }
  1684.  
  1685.  
  1686.  
  1687. // Create the wasm instance.
  1688. // Receives the wasm imports, returns the exports.
  1689. function createWasm() {
  1690. // prepare imports
  1691. var info = {
  1692. 'env': asmLibraryArg,
  1693. 'wasi_snapshot_preview1': asmLibraryArg
  1694. };
  1695. // Load the wasm module and create an instance of using native support in the JS engine.
  1696. // handle a generated wasm instance, receiving its exports and
  1697. // performing other necessary setup
  1698. /** @param {WebAssembly.Module=} module*/
  1699. function receiveInstance(instance, module) {
  1700. var exports = instance.exports;
  1701. Module['asm'] = exports;
  1702. removeRunDependency('wasm-instantiate');
  1703. }
  1704. // we can't run yet (except in a pthread, where we have a custom sync instantiator)
  1705. addRunDependency('wasm-instantiate');
  1706.  
  1707.  
  1708. function receiveInstantiatedSource(output) {
  1709. // 'output' is a WebAssemblyInstantiatedSource object which has both the module and instance.
  1710. // receiveInstance() will swap in the exports (to Module.asm) so they can be called
  1711. // 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.
  1712. // When the regression is fixed, can restore the above USE_PTHREADS-enabled path.
  1713. receiveInstance(output['instance']);
  1714. }
  1715.  
  1716.  
  1717. function instantiateArrayBuffer(receiver) {
  1718. return getBinaryPromise().then(function(binary) {
  1719. return WebAssembly.instantiate(binary, info);
  1720. }).then(receiver, function(reason) {
  1721. err('failed to asynchronously prepare wasm: ' + reason);
  1722. abort(reason);
  1723. });
  1724. }
  1725.  
  1726. // Prefer streaming instantiation if available.
  1727. function instantiateAsync() {
  1728. if (!wasmBinary &&
  1729. typeof WebAssembly.instantiateStreaming === 'function' &&
  1730. !isDataURI(wasmBinaryFile) &&
  1731. // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously.
  1732. !isFileURI(wasmBinaryFile) &&
  1733. typeof fetch === 'function') {
  1734. fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function (response) {
  1735. var result = WebAssembly.instantiateStreaming(response, info);
  1736. return result.then(receiveInstantiatedSource, function(reason) {
  1737. // We expect the most common failure cause to be a bad MIME type for the binary,
  1738. // in which case falling back to ArrayBuffer instantiation should work.
  1739. err('wasm streaming compile failed: ' + reason);
  1740. err('falling back to ArrayBuffer instantiation');
  1741. instantiateArrayBuffer(receiveInstantiatedSource);
  1742. });
  1743. });
  1744. } else {
  1745. return instantiateArrayBuffer(receiveInstantiatedSource);
  1746. }
  1747. }
  1748. // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
  1749. // to manually instantiate the Wasm module themselves. This allows pages to run the instantiation parallel
  1750. // to any other async startup actions they are performing.
  1751. if (Module['instantiateWasm']) {
  1752. try {
  1753. var exports = Module['instantiateWasm'](info, receiveInstance);
  1754. return exports;
  1755. } catch(e) {
  1756. err('Module.instantiateWasm callback failed with error: ' + e);
  1757. return false;
  1758. }
  1759. }
  1760.  
  1761. instantiateAsync();
  1762. return {}; // no exports yet; we'll fill them in later
  1763. }
  1764.  
  1765.  
  1766. // Globals used by JS i64 conversions
  1767. var tempDouble;
  1768. var tempI64;
  1769.  
  1770. // === Body ===
  1771.  
  1772. var ASM_CONSTS = {
  1773.  
  1774. };
  1775.  
  1776.  
  1777.  
  1778.  
  1779. // STATICTOP = STATIC_BASE + 976768;
  1780. /* global initializers */ __ATINIT__.push({ func: function() { ___wasm_call_ctors() } });
  1781.  
  1782.  
  1783.  
  1784.  
  1785. /* no memory initializer */
  1786. // {{PRE_LIBRARY}}
  1787.  
  1788.  
  1789. function demangle(func) {
  1790. return func;
  1791. }
  1792.  
  1793. function demangleAll(text) {
  1794. var regex =
  1795. /\b_Z[\w\d_]+/g;
  1796. return text.replace(regex,
  1797. function(x) {
  1798. var y = demangle(x);
  1799. return x === y ? x : (y + ' [' + x + ']');
  1800. });
  1801. }
  1802.  
  1803. function jsStackTrace() {
  1804. var err = new Error();
  1805. if (!err.stack) {
  1806. // IE10+ special cases: It does have callstack info, but it is only populated if an Error object is thrown,
  1807. // so try that as a special-case.
  1808. try {
  1809. throw new Error();
  1810. } catch(e) {
  1811. err = e;
  1812. }
  1813. if (!err.stack) {
  1814. return '(no stack trace available)';
  1815. }
  1816. }
  1817. return err.stack.toString();
  1818. }
  1819.  
  1820. function stackTrace() {
  1821. var js = jsStackTrace();
  1822. if (Module['extraStackTrace']) js += '\n' + Module['extraStackTrace']();
  1823. return demangleAll(js);
  1824. }
  1825.  
  1826. function ___assert_fail(condition, filename, line, func) {
  1827. abort('Assertion failed: ' + UTF8ToString(condition) + ', at: ' + [filename ? UTF8ToString(filename) : 'unknown filename', line, func ? UTF8ToString(func) : 'unknown function']);
  1828. }
  1829.  
  1830.  
  1831.  
  1832. var PATH={splitPath:function(filename) {
  1833. var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
  1834. return splitPathRe.exec(filename).slice(1);
  1835. },normalizeArray:function(parts, allowAboveRoot) {
  1836. // if the path tries to go above the root, `up` ends up > 0
  1837. var up = 0;
  1838. for (var i = parts.length - 1; i >= 0; i--) {
  1839. var last = parts[i];
  1840. if (last === '.') {
  1841. parts.splice(i, 1);
  1842. } else if (last === '..') {
  1843. parts.splice(i, 1);
  1844. up++;
  1845. } else if (up) {
  1846. parts.splice(i, 1);
  1847. up--;
  1848. }
  1849. }
  1850. // if the path is allowed to go above the root, restore leading ..s
  1851. if (allowAboveRoot) {
  1852. for (; up; up--) {
  1853. parts.unshift('..');
  1854. }
  1855. }
  1856. return parts;
  1857. },normalize:function(path) {
  1858. var isAbsolute = path.charAt(0) === '/',
  1859. trailingSlash = path.substr(-1) === '/';
  1860. // Normalize the path
  1861. path = PATH.normalizeArray(path.split('/').filter(function(p) {
  1862. return !!p;
  1863. }), !isAbsolute).join('/');
  1864. if (!path && !isAbsolute) {
  1865. path = '.';
  1866. }
  1867. if (path && trailingSlash) {
  1868. path += '/';
  1869. }
  1870. return (isAbsolute ? '/' : '') + path;
  1871. },dirname:function(path) {
  1872. var result = PATH.splitPath(path),
  1873. root = result[0],
  1874. dir = result[1];
  1875. if (!root && !dir) {
  1876. // No dirname whatsoever
  1877. return '.';
  1878. }
  1879. if (dir) {
  1880. // It has a dirname, strip trailing slash
  1881. dir = dir.substr(0, dir.length - 1);
  1882. }
  1883. return root + dir;
  1884. },basename:function(path) {
  1885. // EMSCRIPTEN return '/'' for '/', not an empty string
  1886. if (path === '/') return '/';
  1887. var lastSlash = path.lastIndexOf('/');
  1888. if (lastSlash === -1) return path;
  1889. return path.substr(lastSlash+1);
  1890. },extname:function(path) {
  1891. return PATH.splitPath(path)[3];
  1892. },join:function() {
  1893. var paths = Array.prototype.slice.call(arguments, 0);
  1894. return PATH.normalize(paths.join('/'));
  1895. },join2:function(l, r) {
  1896. return PATH.normalize(l + '/' + r);
  1897. }};
  1898.  
  1899.  
  1900. function setErrNo(value) {
  1901. HEAP32[((___errno_location())>>2)]=value;
  1902. return value;
  1903. }
  1904.  
  1905. var PATH_FS={resolve:function() {
  1906. var resolvedPath = '',
  1907. resolvedAbsolute = false;
  1908. for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
  1909. var path = (i >= 0) ? arguments[i] : FS.cwd();
  1910. // Skip empty and invalid entries
  1911. if (typeof path !== 'string') {
  1912. throw new TypeError('Arguments to path.resolve must be strings');
  1913. } else if (!path) {
  1914. return ''; // an invalid portion invalidates the whole thing
  1915. }
  1916. resolvedPath = path + '/' + resolvedPath;
  1917. resolvedAbsolute = path.charAt(0) === '/';
  1918. }
  1919. // At this point the path should be resolved to a full absolute path, but
  1920. // handle relative paths to be safe (might happen when process.cwd() fails)
  1921. resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) {
  1922. return !!p;
  1923. }), !resolvedAbsolute).join('/');
  1924. return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
  1925. },relative:function(from, to) {
  1926. from = PATH_FS.resolve(from).substr(1);
  1927. to = PATH_FS.resolve(to).substr(1);
  1928. function trim(arr) {
  1929. var start = 0;
  1930. for (; start < arr.length; start++) {
  1931. if (arr[start] !== '') break;
  1932. }
  1933. var end = arr.length - 1;
  1934. for (; end >= 0; end--) {
  1935. if (arr[end] !== '') break;
  1936. }
  1937. if (start > end) return [];
  1938. return arr.slice(start, end - start + 1);
  1939. }
  1940. var fromParts = trim(from.split('/'));
  1941. var toParts = trim(to.split('/'));
  1942. var length = Math.min(fromParts.length, toParts.length);
  1943. var samePartsLength = length;
  1944. for (var i = 0; i < length; i++) {
  1945. if (fromParts[i] !== toParts[i]) {
  1946. samePartsLength = i;
  1947. break;
  1948. }
  1949. }
  1950. var outputParts = [];
  1951. for (var i = samePartsLength; i < fromParts.length; i++) {
  1952. outputParts.push('..');
  1953. }
  1954. outputParts = outputParts.concat(toParts.slice(samePartsLength));
  1955. return outputParts.join('/');
  1956. }};
  1957.  
  1958. var TTY={ttys:[],init:function () {
  1959. // https://github.com/emscripten-core/emscripten/pull/1555
  1960. // if (ENVIRONMENT_IS_NODE) {
  1961. // // currently, FS.init does not distinguish if process.stdin is a file or TTY
  1962. // // device, it always assumes it's a TTY device. because of this, we're forcing
  1963. // // process.stdin to UTF8 encoding to at least make stdin reading compatible
  1964. // // with text files until FS.init can be refactored.
  1965. // process['stdin']['setEncoding']('utf8');
  1966. // }
  1967. },shutdown:function() {
  1968. // https://github.com/emscripten-core/emscripten/pull/1555
  1969. // if (ENVIRONMENT_IS_NODE) {
  1970. // // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
  1971. // // 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
  1972. // // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
  1973. // // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
  1974. // // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
  1975. // process['stdin']['pause']();
  1976. // }
  1977. },register:function(dev, ops) {
  1978. TTY.ttys[dev] = { input: [], output: [], ops: ops };
  1979. FS.registerDevice(dev, TTY.stream_ops);
  1980. },stream_ops:{open:function(stream) {
  1981. var tty = TTY.ttys[stream.node.rdev];
  1982. if (!tty) {
  1983. throw new FS.ErrnoError(43);
  1984. }
  1985. stream.tty = tty;
  1986. stream.seekable = false;
  1987. },close:function(stream) {
  1988. // flush any pending line data
  1989. stream.tty.ops.flush(stream.tty);
  1990. },flush:function(stream) {
  1991. stream.tty.ops.flush(stream.tty);
  1992. },read:function(stream, buffer, offset, length, pos /* ignored */) {
  1993. if (!stream.tty || !stream.tty.ops.get_char) {
  1994. throw new FS.ErrnoError(60);
  1995. }
  1996. var bytesRead = 0;
  1997. for (var i = 0; i < length; i++) {
  1998. var result;
  1999. try {
  2000. result = stream.tty.ops.get_char(stream.tty);
  2001. } catch (e) {
  2002. throw new FS.ErrnoError(29);
  2003. }
  2004. if (result === undefined && bytesRead === 0) {
  2005. throw new FS.ErrnoError(6);
  2006. }
  2007. if (result === null || result === undefined) break;
  2008. bytesRead++;
  2009. buffer[offset+i] = result;
  2010. }
  2011. if (bytesRead) {
  2012. stream.node.timestamp = Date.now();
  2013. }
  2014. return bytesRead;
  2015. },write:function(stream, buffer, offset, length, pos) {
  2016. if (!stream.tty || !stream.tty.ops.put_char) {
  2017. throw new FS.ErrnoError(60);
  2018. }
  2019. try {
  2020. for (var i = 0; i < length; i++) {
  2021. stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
  2022. }
  2023. } catch (e) {
  2024. throw new FS.ErrnoError(29);
  2025. }
  2026. if (length) {
  2027. stream.node.timestamp = Date.now();
  2028. }
  2029. return i;
  2030. }},default_tty_ops:{get_char:function(tty) {
  2031. if (!tty.input.length) {
  2032. var result = null;
  2033. if (ENVIRONMENT_IS_NODE) {
  2034. // we will read data by chunks of BUFSIZE
  2035. var BUFSIZE = 256;
  2036. var buf = Buffer.alloc ? Buffer.alloc(BUFSIZE) : new Buffer(BUFSIZE);
  2037. var bytesRead = 0;
  2038.  
  2039. try {
  2040. bytesRead = nodeFS.readSync(process.stdin.fd, buf, 0, BUFSIZE, null);
  2041. } catch(e) {
  2042. // Cross-platform differences: on Windows, reading EOF throws an exception, but on other OSes,
  2043. // reading EOF returns 0. Uniformize behavior by treating the EOF exception to return 0.
  2044. if (e.toString().indexOf('EOF') != -1) bytesRead = 0;
  2045. else throw e;
  2046. }
  2047.  
  2048. if (bytesRead > 0) {
  2049. result = buf.slice(0, bytesRead).toString('utf-8');
  2050. } else {
  2051. result = null;
  2052. }
  2053. } else
  2054. if (typeof window != 'undefined' &&
  2055. typeof window.prompt == 'function') {
  2056. // Browser.
  2057. result = window.prompt('Input: '); // returns null on cancel
  2058. if (result !== null) {
  2059. result += '\n';
  2060. }
  2061. } else if (typeof readline == 'function') {
  2062. // Command line.
  2063. result = readline();
  2064. if (result !== null) {
  2065. result += '\n';
  2066. }
  2067. }
  2068. if (!result) {
  2069. return null;
  2070. }
  2071. tty.input = intArrayFromString(result, true);
  2072. }
  2073. return tty.input.shift();
  2074. },put_char:function(tty, val) {
  2075. if (val === null || val === 10) {
  2076. out(UTF8ArrayToString(tty.output, 0));
  2077. tty.output = [];
  2078. } else {
  2079. if (val != 0) tty.output.push(val); // val == 0 would cut text output off in the middle.
  2080. }
  2081. },flush:function(tty) {
  2082. if (tty.output && tty.output.length > 0) {
  2083. out(UTF8ArrayToString(tty.output, 0));
  2084. tty.output = [];
  2085. }
  2086. }},default_tty1_ops:{put_char:function(tty, val) {
  2087. if (val === null || val === 10) {
  2088. err(UTF8ArrayToString(tty.output, 0));
  2089. tty.output = [];
  2090. } else {
  2091. if (val != 0) tty.output.push(val);
  2092. }
  2093. },flush:function(tty) {
  2094. if (tty.output && tty.output.length > 0) {
  2095. err(UTF8ArrayToString(tty.output, 0));
  2096. tty.output = [];
  2097. }
  2098. }}};
  2099.  
  2100. var MEMFS={ops_table:null,mount:function(mount) {
  2101. return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
  2102. },createNode:function(parent, name, mode, dev) {
  2103. if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
  2104. // no supported
  2105. throw new FS.ErrnoError(63);
  2106. }
  2107. if (!MEMFS.ops_table) {
  2108. MEMFS.ops_table = {
  2109. dir: {
  2110. node: {
  2111. getattr: MEMFS.node_ops.getattr,
  2112. setattr: MEMFS.node_ops.setattr,
  2113. lookup: MEMFS.node_ops.lookup,
  2114. mknod: MEMFS.node_ops.mknod,
  2115. rename: MEMFS.node_ops.rename,
  2116. unlink: MEMFS.node_ops.unlink,
  2117. rmdir: MEMFS.node_ops.rmdir,
  2118. readdir: MEMFS.node_ops.readdir,
  2119. symlink: MEMFS.node_ops.symlink
  2120. },
  2121. stream: {
  2122. llseek: MEMFS.stream_ops.llseek
  2123. }
  2124. },
  2125. file: {
  2126. node: {
  2127. getattr: MEMFS.node_ops.getattr,
  2128. setattr: MEMFS.node_ops.setattr
  2129. },
  2130. stream: {
  2131. llseek: MEMFS.stream_ops.llseek,
  2132. read: MEMFS.stream_ops.read,
  2133. write: MEMFS.stream_ops.write,
  2134. allocate: MEMFS.stream_ops.allocate,
  2135. mmap: MEMFS.stream_ops.mmap,
  2136. msync: MEMFS.stream_ops.msync
  2137. }
  2138. },
  2139. link: {
  2140. node: {
  2141. getattr: MEMFS.node_ops.getattr,
  2142. setattr: MEMFS.node_ops.setattr,
  2143. readlink: MEMFS.node_ops.readlink
  2144. },
  2145. stream: {}
  2146. },
  2147. chrdev: {
  2148. node: {
  2149. getattr: MEMFS.node_ops.getattr,
  2150. setattr: MEMFS.node_ops.setattr
  2151. },
  2152. stream: FS.chrdev_stream_ops
  2153. }
  2154. };
  2155. }
  2156. var node = FS.createNode(parent, name, mode, dev);
  2157. if (FS.isDir(node.mode)) {
  2158. node.node_ops = MEMFS.ops_table.dir.node;
  2159. node.stream_ops = MEMFS.ops_table.dir.stream;
  2160. node.contents = {};
  2161. } else if (FS.isFile(node.mode)) {
  2162. node.node_ops = MEMFS.ops_table.file.node;
  2163. node.stream_ops = MEMFS.ops_table.file.stream;
  2164. node.usedBytes = 0; // The actual number of bytes used in the typed array, as opposed to contents.length which gives the whole capacity.
  2165. // 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
  2166. // for performance, and used by default. However, typed arrays are not resizable like normal JS arrays are, so there is a small disk size
  2167. // penalty involved for appending file writes that continuously grow a file similar to std::vector capacity vs used -scheme.
  2168. node.contents = null;
  2169. } else if (FS.isLink(node.mode)) {
  2170. node.node_ops = MEMFS.ops_table.link.node;
  2171. node.stream_ops = MEMFS.ops_table.link.stream;
  2172. } else if (FS.isChrdev(node.mode)) {
  2173. node.node_ops = MEMFS.ops_table.chrdev.node;
  2174. node.stream_ops = MEMFS.ops_table.chrdev.stream;
  2175. }
  2176. node.timestamp = Date.now();
  2177. // add the new node to the parent
  2178. if (parent) {
  2179. parent.contents[name] = node;
  2180. }
  2181. return node;
  2182. },getFileDataAsRegularArray:function(node) {
  2183. if (node.contents && node.contents.subarray) {
  2184. var arr = [];
  2185. for (var i = 0; i < node.usedBytes; ++i) arr.push(node.contents[i]);
  2186. return arr; // Returns a copy of the original data.
  2187. }
  2188. return node.contents; // No-op, the file contents are already in a JS array. Return as-is.
  2189. },getFileDataAsTypedArray:function(node) {
  2190. if (!node.contents) return new Uint8Array(0);
  2191. if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.
  2192. return new Uint8Array(node.contents);
  2193. },expandFileStorage:function(node, newCapacity) {
  2194. var prevCapacity = node.contents ? node.contents.length : 0;
  2195. if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.
  2196. // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.
  2197. // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to
  2198. // avoid overshooting the allocation cap by a very large margin.
  2199. var CAPACITY_DOUBLING_MAX = 1024 * 1024;
  2200. newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>> 0);
  2201. if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.
  2202. var oldContents = node.contents;
  2203. node.contents = new Uint8Array(newCapacity); // Allocate new storage.
  2204. if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); // Copy old data over to the new storage.
  2205. return;
  2206. },resizeFileStorage:function(node, newSize) {
  2207. if (node.usedBytes == newSize) return;
  2208. if (newSize == 0) {
  2209. node.contents = null; // Fully decommit when requesting a resize to zero.
  2210. node.usedBytes = 0;
  2211. return;
  2212. }
  2213. if (!node.contents || node.contents.subarray) { // Resize a typed array if that is being used as the backing store.
  2214. var oldContents = node.contents;
  2215. node.contents = new Uint8Array(newSize); // Allocate new storage.
  2216. if (oldContents) {
  2217. node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
  2218. }
  2219. node.usedBytes = newSize;
  2220. return;
  2221. }
  2222. // Backing with a JS array.
  2223. if (!node.contents) node.contents = [];
  2224. if (node.contents.length > newSize) node.contents.length = newSize;
  2225. else while (node.contents.length < newSize) node.contents.push(0);
  2226. node.usedBytes = newSize;
  2227. },node_ops:{getattr:function(node) {
  2228. var attr = {};
  2229. // device numbers reuse inode numbers.
  2230. attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
  2231. attr.ino = node.id;
  2232. attr.mode = node.mode;
  2233. attr.nlink = 1;
  2234. attr.uid = 0;
  2235. attr.gid = 0;
  2236. attr.rdev = node.rdev;
  2237. if (FS.isDir(node.mode)) {
  2238. attr.size = 4096;
  2239. } else if (FS.isFile(node.mode)) {
  2240. attr.size = node.usedBytes;
  2241. } else if (FS.isLink(node.mode)) {
  2242. attr.size = node.link.length;
  2243. } else {
  2244. attr.size = 0;
  2245. }
  2246. attr.atime = new Date(node.timestamp);
  2247. attr.mtime = new Date(node.timestamp);
  2248. attr.ctime = new Date(node.timestamp);
  2249. // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
  2250. // but this is not required by the standard.
  2251. attr.blksize = 4096;
  2252. attr.blocks = Math.ceil(attr.size / attr.blksize);
  2253. return attr;
  2254. },setattr:function(node, attr) {
  2255. if (attr.mode !== undefined) {
  2256. node.mode = attr.mode;
  2257. }
  2258. if (attr.timestamp !== undefined) {
  2259. node.timestamp = attr.timestamp;
  2260. }
  2261. if (attr.size !== undefined) {
  2262. MEMFS.resizeFileStorage(node, attr.size);
  2263. }
  2264. },lookup:function(parent, name) {
  2265. throw FS.genericErrors[44];
  2266. },mknod:function(parent, name, mode, dev) {
  2267. return MEMFS.createNode(parent, name, mode, dev);
  2268. },rename:function(old_node, new_dir, new_name) {
  2269. // if we're overwriting a directory at new_name, make sure it's empty.
  2270. if (FS.isDir(old_node.mode)) {
  2271. var new_node;
  2272. try {
  2273. new_node = FS.lookupNode(new_dir, new_name);
  2274. } catch (e) {
  2275. }
  2276. if (new_node) {
  2277. for (var i in new_node.contents) {
  2278. throw new FS.ErrnoError(55);
  2279. }
  2280. }
  2281. }
  2282. // do the internal rewiring
  2283. delete old_node.parent.contents[old_node.name];
  2284. old_node.name = new_name;
  2285. new_dir.contents[new_name] = old_node;
  2286. old_node.parent = new_dir;
  2287. },unlink:function(parent, name) {
  2288. delete parent.contents[name];
  2289. },rmdir:function(parent, name) {
  2290. var node = FS.lookupNode(parent, name);
  2291. for (var i in node.contents) {
  2292. throw new FS.ErrnoError(55);
  2293. }
  2294. delete parent.contents[name];
  2295. },readdir:function(node) {
  2296. var entries = ['.', '..'];
  2297. for (var key in node.contents) {
  2298. if (!node.contents.hasOwnProperty(key)) {
  2299. continue;
  2300. }
  2301. entries.push(key);
  2302. }
  2303. return entries;
  2304. },symlink:function(parent, newname, oldpath) {
  2305. var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
  2306. node.link = oldpath;
  2307. return node;
  2308. },readlink:function(node) {
  2309. if (!FS.isLink(node.mode)) {
  2310. throw new FS.ErrnoError(28);
  2311. }
  2312. return node.link;
  2313. }},stream_ops:{read:function(stream, buffer, offset, length, position) {
  2314. var contents = stream.node.contents;
  2315. if (position >= stream.node.usedBytes) return 0;
  2316. var size = Math.min(stream.node.usedBytes - position, length);
  2317. if (size > 8 && contents.subarray) { // non-trivial, and typed array
  2318. buffer.set(contents.subarray(position, position + size), offset);
  2319. } else {
  2320. for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
  2321. }
  2322. return size;
  2323. },write:function(stream, buffer, offset, length, position, canOwn) {
  2324.  
  2325. if (!length) return 0;
  2326. var node = stream.node;
  2327. node.timestamp = Date.now();
  2328.  
  2329. if (buffer.subarray && (!node.contents || node.contents.subarray)) { // This write is from a typed array to a typed array?
  2330. if (canOwn) {
  2331. node.contents = buffer.subarray(offset, offset + length);
  2332. node.usedBytes = length;
  2333. return length;
  2334. } 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.
  2335. node.contents = buffer.slice(offset, offset + length);
  2336. node.usedBytes = length;
  2337. return length;
  2338. } else if (position + length <= node.usedBytes) { // Writing to an already allocated and used subrange of the file?
  2339. node.contents.set(buffer.subarray(offset, offset + length), position);
  2340. return length;
  2341. }
  2342. }
  2343.  
  2344. // Appending to an existing file and we need to reallocate, or source data did not come as a typed array.
  2345. MEMFS.expandFileStorage(node, position+length);
  2346. if (node.contents.subarray && buffer.subarray) node.contents.set(buffer.subarray(offset, offset + length), position); // Use typed array write if available.
  2347. else {
  2348. for (var i = 0; i < length; i++) {
  2349. node.contents[position + i] = buffer[offset + i]; // Or fall back to manual write if not.
  2350. }
  2351. }
  2352. node.usedBytes = Math.max(node.usedBytes, position + length);
  2353. return length;
  2354. },llseek:function(stream, offset, whence) {
  2355. var position = offset;
  2356. if (whence === 1) {
  2357. position += stream.position;
  2358. } else if (whence === 2) {
  2359. if (FS.isFile(stream.node.mode)) {
  2360. position += stream.node.usedBytes;
  2361. }
  2362. }
  2363. if (position < 0) {
  2364. throw new FS.ErrnoError(28);
  2365. }
  2366. return position;
  2367. },allocate:function(stream, offset, length) {
  2368. MEMFS.expandFileStorage(stream.node, offset + length);
  2369. stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length);
  2370. },mmap:function(stream, buffer, offset, length, position, prot, flags) {
  2371. if (!FS.isFile(stream.node.mode)) {
  2372. throw new FS.ErrnoError(43);
  2373. }
  2374. var ptr;
  2375. var allocated;
  2376. var contents = stream.node.contents;
  2377. // Only make a new copy when MAP_PRIVATE is specified.
  2378. if ( !(flags & 2) &&
  2379. contents.buffer === buffer.buffer ) {
  2380. // We can't emulate MAP_SHARED when the file is not backed by the buffer
  2381. // we're mapping to (e.g. the HEAP buffer).
  2382. allocated = false;
  2383. ptr = contents.byteOffset;
  2384. } else {
  2385. // Try to avoid unnecessary slices.
  2386. if (position > 0 || position + length < contents.length) {
  2387. if (contents.subarray) {
  2388. contents = contents.subarray(position, position + length);
  2389. } else {
  2390. contents = Array.prototype.slice.call(contents, position, position + length);
  2391. }
  2392. }
  2393. allocated = true;
  2394. // malloc() can lead to growing the heap. If targeting the heap, we need to
  2395. // re-acquire the heap buffer object in case growth had occurred.
  2396. var fromHeap = (buffer.buffer == HEAP8.buffer);
  2397. ptr = _malloc(length);
  2398. if (!ptr) {
  2399. throw new FS.ErrnoError(48);
  2400. }
  2401. (fromHeap ? HEAP8 : buffer).set(contents, ptr);
  2402. }
  2403. return { ptr: ptr, allocated: allocated };
  2404. },msync:function(stream, buffer, offset, length, mmapFlags) {
  2405. if (!FS.isFile(stream.node.mode)) {
  2406. throw new FS.ErrnoError(43);
  2407. }
  2408. if (mmapFlags & 2) {
  2409. // MAP_PRIVATE calls need not to be synced back to underlying fs
  2410. return 0;
  2411. }
  2412.  
  2413. var bytesWritten = MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);
  2414. // should we check if bytesWritten and length are the same?
  2415. return 0;
  2416. }}};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,trackingDelegate:{},tracking:{openFlags:{READ:1,WRITE:2}},ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,handleFSError:function(e) {
  2417. if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace();
  2418. return setErrNo(e.errno);
  2419. },lookupPath:function(path, opts) {
  2420. path = PATH_FS.resolve(FS.cwd(), path);
  2421. opts = opts || {};
  2422.  
  2423. if (!path) return { path: '', node: null };
  2424.  
  2425. var defaults = {
  2426. follow_mount: true,
  2427. recurse_count: 0
  2428. };
  2429. for (var key in defaults) {
  2430. if (opts[key] === undefined) {
  2431. opts[key] = defaults[key];
  2432. }
  2433. }
  2434.  
  2435. if (opts.recurse_count > 8) { // max recursive lookup of 8
  2436. throw new FS.ErrnoError(32);
  2437. }
  2438.  
  2439. // split the path
  2440. var parts = PATH.normalizeArray(path.split('/').filter(function(p) {
  2441. return !!p;
  2442. }), false);
  2443.  
  2444. // start at the root
  2445. var current = FS.root;
  2446. var current_path = '/';
  2447.  
  2448. for (var i = 0; i < parts.length; i++) {
  2449. var islast = (i === parts.length-1);
  2450. if (islast && opts.parent) {
  2451. // stop resolving
  2452. break;
  2453. }
  2454.  
  2455. current = FS.lookupNode(current, parts[i]);
  2456. current_path = PATH.join2(current_path, parts[i]);
  2457.  
  2458. // jump to the mount's root node if this is a mountpoint
  2459. if (FS.isMountpoint(current)) {
  2460. if (!islast || (islast && opts.follow_mount)) {
  2461. current = current.mounted.root;
  2462. }
  2463. }
  2464.  
  2465. // by default, lookupPath will not follow a symlink if it is the final path component.
  2466. // setting opts.follow = true will override this behavior.
  2467. if (!islast || opts.follow) {
  2468. var count = 0;
  2469. while (FS.isLink(current.mode)) {
  2470. var link = FS.readlink(current_path);
  2471. current_path = PATH_FS.resolve(PATH.dirname(current_path), link);
  2472.  
  2473. var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count });
  2474. current = lookup.node;
  2475.  
  2476. if (count++ > 40) { // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
  2477. throw new FS.ErrnoError(32);
  2478. }
  2479. }
  2480. }
  2481. }
  2482.  
  2483. return { path: current_path, node: current };
  2484. },getPath:function(node) {
  2485. var path;
  2486. while (true) {
  2487. if (FS.isRoot(node)) {
  2488. var mount = node.mount.mountpoint;
  2489. if (!path) return mount;
  2490. return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;
  2491. }
  2492. path = path ? node.name + '/' + path : node.name;
  2493. node = node.parent;
  2494. }
  2495. },hashName:function(parentid, name) {
  2496. var hash = 0;
  2497.  
  2498.  
  2499. for (var i = 0; i < name.length; i++) {
  2500. hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
  2501. }
  2502. return ((parentid + hash) >>> 0) % FS.nameTable.length;
  2503. },hashAddNode:function(node) {
  2504. var hash = FS.hashName(node.parent.id, node.name);
  2505. node.name_next = FS.nameTable[hash];
  2506. FS.nameTable[hash] = node;
  2507. },hashRemoveNode:function(node) {
  2508. var hash = FS.hashName(node.parent.id, node.name);
  2509. if (FS.nameTable[hash] === node) {
  2510. FS.nameTable[hash] = node.name_next;
  2511. } else {
  2512. var current = FS.nameTable[hash];
  2513. while (current) {
  2514. if (current.name_next === node) {
  2515. current.name_next = node.name_next;
  2516. break;
  2517. }
  2518. current = current.name_next;
  2519. }
  2520. }
  2521. },lookupNode:function(parent, name) {
  2522. var errCode = FS.mayLookup(parent);
  2523. if (errCode) {
  2524. throw new FS.ErrnoError(errCode, parent);
  2525. }
  2526. var hash = FS.hashName(parent.id, name);
  2527. for (var node = FS.nameTable[hash]; node; node = node.name_next) {
  2528. var nodeName = node.name;
  2529. if (node.parent.id === parent.id && nodeName === name) {
  2530. return node;
  2531. }
  2532. }
  2533. // if we failed to find it in the cache, call into the VFS
  2534. return FS.lookup(parent, name);
  2535. },createNode:function(parent, name, mode, rdev) {
  2536. var node = new FS.FSNode(parent, name, mode, rdev);
  2537.  
  2538. FS.hashAddNode(node);
  2539.  
  2540. return node;
  2541. },destroyNode:function(node) {
  2542. FS.hashRemoveNode(node);
  2543. },isRoot:function(node) {
  2544. return node === node.parent;
  2545. },isMountpoint:function(node) {
  2546. return !!node.mounted;
  2547. },isFile:function(mode) {
  2548. return (mode & 61440) === 32768;
  2549. },isDir:function(mode) {
  2550. return (mode & 61440) === 16384;
  2551. },isLink:function(mode) {
  2552. return (mode & 61440) === 40960;
  2553. },isChrdev:function(mode) {
  2554. return (mode & 61440) === 8192;
  2555. },isBlkdev:function(mode) {
  2556. return (mode & 61440) === 24576;
  2557. },isFIFO:function(mode) {
  2558. return (mode & 61440) === 4096;
  2559. },isSocket:function(mode) {
  2560. return (mode & 49152) === 49152;
  2561. },flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function(str) {
  2562. var flags = FS.flagModes[str];
  2563. if (typeof flags === 'undefined') {
  2564. throw new Error('Unknown file open mode: ' + str);
  2565. }
  2566. return flags;
  2567. },flagsToPermissionString:function(flag) {
  2568. var perms = ['r', 'w', 'rw'][flag & 3];
  2569. if ((flag & 512)) {
  2570. perms += 'w';
  2571. }
  2572. return perms;
  2573. },nodePermissions:function(node, perms) {
  2574. if (FS.ignorePermissions) {
  2575. return 0;
  2576. }
  2577. // return 0 if any user, group or owner bits are set.
  2578. if (perms.indexOf('r') !== -1 && !(node.mode & 292)) {
  2579. return 2;
  2580. } else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) {
  2581. return 2;
  2582. } else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) {
  2583. return 2;
  2584. }
  2585. return 0;
  2586. },mayLookup:function(dir) {
  2587. var errCode = FS.nodePermissions(dir, 'x');
  2588. if (errCode) return errCode;
  2589. if (!dir.node_ops.lookup) return 2;
  2590. return 0;
  2591. },mayCreate:function(dir, name) {
  2592. try {
  2593. var node = FS.lookupNode(dir, name);
  2594. return 20;
  2595. } catch (e) {
  2596. }
  2597. return FS.nodePermissions(dir, 'wx');
  2598. },mayDelete:function(dir, name, isdir) {
  2599. var node;
  2600. try {
  2601. node = FS.lookupNode(dir, name);
  2602. } catch (e) {
  2603. return e.errno;
  2604. }
  2605. var errCode = FS.nodePermissions(dir, 'wx');
  2606. if (errCode) {
  2607. return errCode;
  2608. }
  2609. if (isdir) {
  2610. if (!FS.isDir(node.mode)) {
  2611. return 54;
  2612. }
  2613. if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
  2614. return 10;
  2615. }
  2616. } else {
  2617. if (FS.isDir(node.mode)) {
  2618. return 31;
  2619. }
  2620. }
  2621. return 0;
  2622. },mayOpen:function(node, flags) {
  2623. if (!node) {
  2624. return 44;
  2625. }
  2626. if (FS.isLink(node.mode)) {
  2627. return 32;
  2628. } else if (FS.isDir(node.mode)) {
  2629. if (FS.flagsToPermissionString(flags) !== 'r' || // opening for write
  2630. (flags & 512)) { // TODO: check for O_SEARCH? (== search for dir only)
  2631. return 31;
  2632. }
  2633. }
  2634. return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
  2635. },MAX_OPEN_FDS:4096,nextfd:function(fd_start, fd_end) {
  2636. fd_start = fd_start || 0;
  2637. fd_end = fd_end || FS.MAX_OPEN_FDS;
  2638. for (var fd = fd_start; fd <= fd_end; fd++) {
  2639. if (!FS.streams[fd]) {
  2640. return fd;
  2641. }
  2642. }
  2643. throw new FS.ErrnoError(33);
  2644. },getStream:function(fd) {
  2645. return FS.streams[fd];
  2646. },createStream:function(stream, fd_start, fd_end) {
  2647. if (!FS.FSStream) {
  2648. FS.FSStream = /** @constructor */ function(){};
  2649. FS.FSStream.prototype = {
  2650. object: {
  2651. get: function() { return this.node; },
  2652. set: function(val) { this.node = val; }
  2653. },
  2654. isRead: {
  2655. get: function() { return (this.flags & 2097155) !== 1; }
  2656. },
  2657. isWrite: {
  2658. get: function() { return (this.flags & 2097155) !== 0; }
  2659. },
  2660. isAppend: {
  2661. get: function() { return (this.flags & 1024); }
  2662. }
  2663. };
  2664. }
  2665. // clone it, so we can return an instance of FSStream
  2666. var newStream = new FS.FSStream();
  2667. for (var p in stream) {
  2668. newStream[p] = stream[p];
  2669. }
  2670. stream = newStream;
  2671. var fd = FS.nextfd(fd_start, fd_end);
  2672. stream.fd = fd;
  2673. FS.streams[fd] = stream;
  2674. return stream;
  2675. },closeStream:function(fd) {
  2676. FS.streams[fd] = null;
  2677. },chrdev_stream_ops:{open:function(stream) {
  2678. var device = FS.getDevice(stream.node.rdev);
  2679. // override node's stream ops with the device's
  2680. stream.stream_ops = device.stream_ops;
  2681. // forward the open call
  2682. if (stream.stream_ops.open) {
  2683. stream.stream_ops.open(stream);
  2684. }
  2685. },llseek:function() {
  2686. throw new FS.ErrnoError(70);
  2687. }},major:function(dev) {
  2688. return ((dev) >> 8);
  2689. },minor:function(dev) {
  2690. return ((dev) & 0xff);
  2691. },makedev:function(ma, mi) {
  2692. return ((ma) << 8 | (mi));
  2693. },registerDevice:function(dev, ops) {
  2694. FS.devices[dev] = { stream_ops: ops };
  2695. },getDevice:function(dev) {
  2696. return FS.devices[dev];
  2697. },getMounts:function(mount) {
  2698. var mounts = [];
  2699. var check = [mount];
  2700.  
  2701. while (check.length) {
  2702. var m = check.pop();
  2703.  
  2704. mounts.push(m);
  2705.  
  2706. check.push.apply(check, m.mounts);
  2707. }
  2708.  
  2709. return mounts;
  2710. },syncfs:function(populate, callback) {
  2711. if (typeof(populate) === 'function') {
  2712. callback = populate;
  2713. populate = false;
  2714. }
  2715.  
  2716. FS.syncFSRequests++;
  2717.  
  2718. if (FS.syncFSRequests > 1) {
  2719. err('warning: ' + FS.syncFSRequests + ' FS.syncfs operations in flight at once, probably just doing extra work');
  2720. }
  2721.  
  2722. var mounts = FS.getMounts(FS.root.mount);
  2723. var completed = 0;
  2724.  
  2725. function doCallback(errCode) {
  2726. FS.syncFSRequests--;
  2727. return callback(errCode);
  2728. }
  2729.  
  2730. function done(errCode) {
  2731. if (errCode) {
  2732. if (!done.errored) {
  2733. done.errored = true;
  2734. return doCallback(errCode);
  2735. }
  2736. return;
  2737. }
  2738. if (++completed >= mounts.length) {
  2739. doCallback(null);
  2740. }
  2741. };
  2742.  
  2743. // sync all mounts
  2744. mounts.forEach(function (mount) {
  2745. if (!mount.type.syncfs) {
  2746. return done(null);
  2747. }
  2748. mount.type.syncfs(mount, populate, done);
  2749. });
  2750. },mount:function(type, opts, mountpoint) {
  2751. var root = mountpoint === '/';
  2752. var pseudo = !mountpoint;
  2753. var node;
  2754.  
  2755. if (root && FS.root) {
  2756. throw new FS.ErrnoError(10);
  2757. } else if (!root && !pseudo) {
  2758. var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
  2759.  
  2760. mountpoint = lookup.path; // use the absolute path
  2761. node = lookup.node;
  2762.  
  2763. if (FS.isMountpoint(node)) {
  2764. throw new FS.ErrnoError(10);
  2765. }
  2766.  
  2767. if (!FS.isDir(node.mode)) {
  2768. throw new FS.ErrnoError(54);
  2769. }
  2770. }
  2771.  
  2772. var mount = {
  2773. type: type,
  2774. opts: opts,
  2775. mountpoint: mountpoint,
  2776. mounts: []
  2777. };
  2778.  
  2779. // create a root node for the fs
  2780. var mountRoot = type.mount(mount);
  2781. mountRoot.mount = mount;
  2782. mount.root = mountRoot;
  2783.  
  2784. if (root) {
  2785. FS.root = mountRoot;
  2786. } else if (node) {
  2787. // set as a mountpoint
  2788. node.mounted = mount;
  2789.  
  2790. // add the new mount to the current mount's children
  2791. if (node.mount) {
  2792. node.mount.mounts.push(mount);
  2793. }
  2794. }
  2795.  
  2796. return mountRoot;
  2797. },unmount:function (mountpoint) {
  2798. var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
  2799.  
  2800. if (!FS.isMountpoint(lookup.node)) {
  2801. throw new FS.ErrnoError(28);
  2802. }
  2803.  
  2804. // destroy the nodes for this mount, and all its child mounts
  2805. var node = lookup.node;
  2806. var mount = node.mounted;
  2807. var mounts = FS.getMounts(mount);
  2808.  
  2809. Object.keys(FS.nameTable).forEach(function (hash) {
  2810. var current = FS.nameTable[hash];
  2811.  
  2812. while (current) {
  2813. var next = current.name_next;
  2814.  
  2815. if (mounts.indexOf(current.mount) !== -1) {
  2816. FS.destroyNode(current);
  2817. }
  2818.  
  2819. current = next;
  2820. }
  2821. });
  2822.  
  2823. // no longer a mountpoint
  2824. node.mounted = null;
  2825.  
  2826. // remove this mount from the child mounts
  2827. var idx = node.mount.mounts.indexOf(mount);
  2828. node.mount.mounts.splice(idx, 1);
  2829. },lookup:function(parent, name) {
  2830. return parent.node_ops.lookup(parent, name);
  2831. },mknod:function(path, mode, dev) {
  2832. var lookup = FS.lookupPath(path, { parent: true });
  2833. var parent = lookup.node;
  2834. var name = PATH.basename(path);
  2835. if (!name || name === '.' || name === '..') {
  2836. throw new FS.ErrnoError(28);
  2837. }
  2838. var errCode = FS.mayCreate(parent, name);
  2839. if (errCode) {
  2840. throw new FS.ErrnoError(errCode);
  2841. }
  2842. if (!parent.node_ops.mknod) {
  2843. throw new FS.ErrnoError(63);
  2844. }
  2845. return parent.node_ops.mknod(parent, name, mode, dev);
  2846. },create:function(path, mode) {
  2847. mode = mode !== undefined ? mode : 438 /* 0666 */;
  2848. mode &= 4095;
  2849. mode |= 32768;
  2850. return FS.mknod(path, mode, 0);
  2851. },mkdir:function(path, mode) {
  2852. mode = mode !== undefined ? mode : 511 /* 0777 */;
  2853. mode &= 511 | 512;
  2854. mode |= 16384;
  2855. return FS.mknod(path, mode, 0);
  2856. },mkdirTree:function(path, mode) {
  2857. var dirs = path.split('/');
  2858. var d = '';
  2859. for (var i = 0; i < dirs.length; ++i) {
  2860. if (!dirs[i]) continue;
  2861. d += '/' + dirs[i];
  2862. try {
  2863. FS.mkdir(d, mode);
  2864. } catch(e) {
  2865. if (e.errno != 20) throw e;
  2866. }
  2867. }
  2868. },mkdev:function(path, mode, dev) {
  2869. if (typeof(dev) === 'undefined') {
  2870. dev = mode;
  2871. mode = 438 /* 0666 */;
  2872. }
  2873. mode |= 8192;
  2874. return FS.mknod(path, mode, dev);
  2875. },symlink:function(oldpath, newpath) {
  2876. if (!PATH_FS.resolve(oldpath)) {
  2877. throw new FS.ErrnoError(44);
  2878. }
  2879. var lookup = FS.lookupPath(newpath, { parent: true });
  2880. var parent = lookup.node;
  2881. if (!parent) {
  2882. throw new FS.ErrnoError(44);
  2883. }
  2884. var newname = PATH.basename(newpath);
  2885. var errCode = FS.mayCreate(parent, newname);
  2886. if (errCode) {
  2887. throw new FS.ErrnoError(errCode);
  2888. }
  2889. if (!parent.node_ops.symlink) {
  2890. throw new FS.ErrnoError(63);
  2891. }
  2892. return parent.node_ops.symlink(parent, newname, oldpath);
  2893. },rename:function(old_path, new_path) {
  2894. var old_dirname = PATH.dirname(old_path);
  2895. var new_dirname = PATH.dirname(new_path);
  2896. var old_name = PATH.basename(old_path);
  2897. var new_name = PATH.basename(new_path);
  2898. // parents must exist
  2899. var lookup, old_dir, new_dir;
  2900. try {
  2901. lookup = FS.lookupPath(old_path, { parent: true });
  2902. old_dir = lookup.node;
  2903. lookup = FS.lookupPath(new_path, { parent: true });
  2904. new_dir = lookup.node;
  2905. } catch (e) {
  2906. throw new FS.ErrnoError(10);
  2907. }
  2908. if (!old_dir || !new_dir) throw new FS.ErrnoError(44);
  2909. // need to be part of the same mount
  2910. if (old_dir.mount !== new_dir.mount) {
  2911. throw new FS.ErrnoError(75);
  2912. }
  2913. // source must exist
  2914. var old_node = FS.lookupNode(old_dir, old_name);
  2915. // old path should not be an ancestor of the new path
  2916. var relative = PATH_FS.relative(old_path, new_dirname);
  2917. if (relative.charAt(0) !== '.') {
  2918. throw new FS.ErrnoError(28);
  2919. }
  2920. // new path should not be an ancestor of the old path
  2921. relative = PATH_FS.relative(new_path, old_dirname);
  2922. if (relative.charAt(0) !== '.') {
  2923. throw new FS.ErrnoError(55);
  2924. }
  2925. // see if the new path already exists
  2926. var new_node;
  2927. try {
  2928. new_node = FS.lookupNode(new_dir, new_name);
  2929. } catch (e) {
  2930. // not fatal
  2931. }
  2932. // early out if nothing needs to change
  2933. if (old_node === new_node) {
  2934. return;
  2935. }
  2936. // we'll need to delete the old entry
  2937. var isdir = FS.isDir(old_node.mode);
  2938. var errCode = FS.mayDelete(old_dir, old_name, isdir);
  2939. if (errCode) {
  2940. throw new FS.ErrnoError(errCode);
  2941. }
  2942. // need delete permissions if we'll be overwriting.
  2943. // need create permissions if new doesn't already exist.
  2944. errCode = new_node ?
  2945. FS.mayDelete(new_dir, new_name, isdir) :
  2946. FS.mayCreate(new_dir, new_name);
  2947. if (errCode) {
  2948. throw new FS.ErrnoError(errCode);
  2949. }
  2950. if (!old_dir.node_ops.rename) {
  2951. throw new FS.ErrnoError(63);
  2952. }
  2953. if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
  2954. throw new FS.ErrnoError(10);
  2955. }
  2956. // if we are going to change the parent, check write permissions
  2957. if (new_dir !== old_dir) {
  2958. errCode = FS.nodePermissions(old_dir, 'w');
  2959. if (errCode) {
  2960. throw new FS.ErrnoError(errCode);
  2961. }
  2962. }
  2963. try {
  2964. if (FS.trackingDelegate['willMovePath']) {
  2965. FS.trackingDelegate['willMovePath'](old_path, new_path);
  2966. }
  2967. } catch(e) {
  2968. err("FS.trackingDelegate['willMovePath']('"+old_path+"', '"+new_path+"') threw an exception: " + e.message);
  2969. }
  2970. // remove the node from the lookup hash
  2971. FS.hashRemoveNode(old_node);
  2972. // do the underlying fs rename
  2973. try {
  2974. old_dir.node_ops.rename(old_node, new_dir, new_name);
  2975. } catch (e) {
  2976. throw e;
  2977. } finally {
  2978. // add the node back to the hash (in case node_ops.rename
  2979. // changed its name)
  2980. FS.hashAddNode(old_node);
  2981. }
  2982. try {
  2983. if (FS.trackingDelegate['onMovePath']) FS.trackingDelegate['onMovePath'](old_path, new_path);
  2984. } catch(e) {
  2985. err("FS.trackingDelegate['onMovePath']('"+old_path+"', '"+new_path+"') threw an exception: " + e.message);
  2986. }
  2987. },rmdir:function(path) {
  2988. var lookup = FS.lookupPath(path, { parent: true });
  2989. var parent = lookup.node;
  2990. var name = PATH.basename(path);
  2991. var node = FS.lookupNode(parent, name);
  2992. var errCode = FS.mayDelete(parent, name, true);
  2993. if (errCode) {
  2994. throw new FS.ErrnoError(errCode);
  2995. }
  2996. if (!parent.node_ops.rmdir) {
  2997. throw new FS.ErrnoError(63);
  2998. }
  2999. if (FS.isMountpoint(node)) {
  3000. throw new FS.ErrnoError(10);
  3001. }
  3002. try {
  3003. if (FS.trackingDelegate['willDeletePath']) {
  3004. FS.trackingDelegate['willDeletePath'](path);
  3005. }
  3006. } catch(e) {
  3007. err("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: " + e.message);
  3008. }
  3009. parent.node_ops.rmdir(parent, name);
  3010. FS.destroyNode(node);
  3011. try {
  3012. if (FS.trackingDelegate['onDeletePath']) FS.trackingDelegate['onDeletePath'](path);
  3013. } catch(e) {
  3014. err("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: " + e.message);
  3015. }
  3016. },readdir:function(path) {
  3017. var lookup = FS.lookupPath(path, { follow: true });
  3018. var node = lookup.node;
  3019. if (!node.node_ops.readdir) {
  3020. throw new FS.ErrnoError(54);
  3021. }
  3022. return node.node_ops.readdir(node);
  3023. },unlink:function(path) {
  3024. var lookup = FS.lookupPath(path, { parent: true });
  3025. var parent = lookup.node;
  3026. var name = PATH.basename(path);
  3027. var node = FS.lookupNode(parent, name);
  3028. var errCode = FS.mayDelete(parent, name, false);
  3029. if (errCode) {
  3030. // According to POSIX, we should map EISDIR to EPERM, but
  3031. // we instead do what Linux does (and we must, as we use
  3032. // the musl linux libc).
  3033. throw new FS.ErrnoError(errCode);
  3034. }
  3035. if (!parent.node_ops.unlink) {
  3036. throw new FS.ErrnoError(63);
  3037. }
  3038. if (FS.isMountpoint(node)) {
  3039. throw new FS.ErrnoError(10);
  3040. }
  3041. try {
  3042. if (FS.trackingDelegate['willDeletePath']) {
  3043. FS.trackingDelegate['willDeletePath'](path);
  3044. }
  3045. } catch(e) {
  3046. err("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: " + e.message);
  3047. }
  3048. parent.node_ops.unlink(parent, name);
  3049. FS.destroyNode(node);
  3050. try {
  3051. if (FS.trackingDelegate['onDeletePath']) FS.trackingDelegate['onDeletePath'](path);
  3052. } catch(e) {
  3053. err("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: " + e.message);
  3054. }
  3055. },readlink:function(path) {
  3056. var lookup = FS.lookupPath(path);
  3057. var link = lookup.node;
  3058. if (!link) {
  3059. throw new FS.ErrnoError(44);
  3060. }
  3061. if (!link.node_ops.readlink) {
  3062. throw new FS.ErrnoError(28);
  3063. }
  3064. return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link));
  3065. },stat:function(path, dontFollow) {
  3066. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  3067. var node = lookup.node;
  3068. if (!node) {
  3069. throw new FS.ErrnoError(44);
  3070. }
  3071. if (!node.node_ops.getattr) {
  3072. throw new FS.ErrnoError(63);
  3073. }
  3074. return node.node_ops.getattr(node);
  3075. },lstat:function(path) {
  3076. return FS.stat(path, true);
  3077. },chmod:function(path, mode, dontFollow) {
  3078. var node;
  3079. if (typeof path === 'string') {
  3080. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  3081. node = lookup.node;
  3082. } else {
  3083. node = path;
  3084. }
  3085. if (!node.node_ops.setattr) {
  3086. throw new FS.ErrnoError(63);
  3087. }
  3088. node.node_ops.setattr(node, {
  3089. mode: (mode & 4095) | (node.mode & ~4095),
  3090. timestamp: Date.now()
  3091. });
  3092. },lchmod:function(path, mode) {
  3093. FS.chmod(path, mode, true);
  3094. },fchmod:function(fd, mode) {
  3095. var stream = FS.getStream(fd);
  3096. if (!stream) {
  3097. throw new FS.ErrnoError(8);
  3098. }
  3099. FS.chmod(stream.node, mode);
  3100. },chown:function(path, uid, gid, dontFollow) {
  3101. var node;
  3102. if (typeof path === 'string') {
  3103. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  3104. node = lookup.node;
  3105. } else {
  3106. node = path;
  3107. }
  3108. if (!node.node_ops.setattr) {
  3109. throw new FS.ErrnoError(63);
  3110. }
  3111. node.node_ops.setattr(node, {
  3112. timestamp: Date.now()
  3113. // we ignore the uid / gid for now
  3114. });
  3115. },lchown:function(path, uid, gid) {
  3116. FS.chown(path, uid, gid, true);
  3117. },fchown:function(fd, uid, gid) {
  3118. var stream = FS.getStream(fd);
  3119. if (!stream) {
  3120. throw new FS.ErrnoError(8);
  3121. }
  3122. FS.chown(stream.node, uid, gid);
  3123. },truncate:function(path, len) {
  3124. if (len < 0) {
  3125. throw new FS.ErrnoError(28);
  3126. }
  3127. var node;
  3128. if (typeof path === 'string') {
  3129. var lookup = FS.lookupPath(path, { follow: true });
  3130. node = lookup.node;
  3131. } else {
  3132. node = path;
  3133. }
  3134. if (!node.node_ops.setattr) {
  3135. throw new FS.ErrnoError(63);
  3136. }
  3137. if (FS.isDir(node.mode)) {
  3138. throw new FS.ErrnoError(31);
  3139. }
  3140. if (!FS.isFile(node.mode)) {
  3141. throw new FS.ErrnoError(28);
  3142. }
  3143. var errCode = FS.nodePermissions(node, 'w');
  3144. if (errCode) {
  3145. throw new FS.ErrnoError(errCode);
  3146. }
  3147. node.node_ops.setattr(node, {
  3148. size: len,
  3149. timestamp: Date.now()
  3150. });
  3151. },ftruncate:function(fd, len) {
  3152. var stream = FS.getStream(fd);
  3153. if (!stream) {
  3154. throw new FS.ErrnoError(8);
  3155. }
  3156. if ((stream.flags & 2097155) === 0) {
  3157. throw new FS.ErrnoError(28);
  3158. }
  3159. FS.truncate(stream.node, len);
  3160. },utime:function(path, atime, mtime) {
  3161. var lookup = FS.lookupPath(path, { follow: true });
  3162. var node = lookup.node;
  3163. node.node_ops.setattr(node, {
  3164. timestamp: Math.max(atime, mtime)
  3165. });
  3166. },open:function(path, flags, mode, fd_start, fd_end) {
  3167. if (path === "") {
  3168. throw new FS.ErrnoError(44);
  3169. }
  3170. flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;
  3171. mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode;
  3172. if ((flags & 64)) {
  3173. mode = (mode & 4095) | 32768;
  3174. } else {
  3175. mode = 0;
  3176. }
  3177. var node;
  3178. if (typeof path === 'object') {
  3179. node = path;
  3180. } else {
  3181. path = PATH.normalize(path);
  3182. try {
  3183. var lookup = FS.lookupPath(path, {
  3184. follow: !(flags & 131072)
  3185. });
  3186. node = lookup.node;
  3187. } catch (e) {
  3188. // ignore
  3189. }
  3190. }
  3191. // perhaps we need to create the node
  3192. var created = false;
  3193. if ((flags & 64)) {
  3194. if (node) {
  3195. // if O_CREAT and O_EXCL are set, error out if the node already exists
  3196. if ((flags & 128)) {
  3197. throw new FS.ErrnoError(20);
  3198. }
  3199. } else {
  3200. // node doesn't exist, try to create it
  3201. node = FS.mknod(path, mode, 0);
  3202. created = true;
  3203. }
  3204. }
  3205. if (!node) {
  3206. throw new FS.ErrnoError(44);
  3207. }
  3208. // can't truncate a device
  3209. if (FS.isChrdev(node.mode)) {
  3210. flags &= ~512;
  3211. }
  3212. // if asked only for a directory, then this must be one
  3213. if ((flags & 65536) && !FS.isDir(node.mode)) {
  3214. throw new FS.ErrnoError(54);
  3215. }
  3216. // check permissions, if this is not a file we just created now (it is ok to
  3217. // create and write to a file with read-only permissions; it is read-only
  3218. // for later use)
  3219. if (!created) {
  3220. var errCode = FS.mayOpen(node, flags);
  3221. if (errCode) {
  3222. throw new FS.ErrnoError(errCode);
  3223. }
  3224. }
  3225. // do truncation if necessary
  3226. if ((flags & 512)) {
  3227. FS.truncate(node, 0);
  3228. }
  3229. // we've already handled these, don't pass down to the underlying vfs
  3230. flags &= ~(128 | 512 | 131072);
  3231.  
  3232. // register the stream with the filesystem
  3233. var stream = FS.createStream({
  3234. node: node,
  3235. path: FS.getPath(node), // we want the absolute path to the node
  3236. flags: flags,
  3237. seekable: true,
  3238. position: 0,
  3239. stream_ops: node.stream_ops,
  3240. // used by the file family libc calls (fopen, fwrite, ferror, etc.)
  3241. ungotten: [],
  3242. error: false
  3243. }, fd_start, fd_end);
  3244. // call the new stream's open function
  3245. if (stream.stream_ops.open) {
  3246. stream.stream_ops.open(stream);
  3247. }
  3248. if (Module['logReadFiles'] && !(flags & 1)) {
  3249. if (!FS.readFiles) FS.readFiles = {};
  3250. if (!(path in FS.readFiles)) {
  3251. FS.readFiles[path] = 1;
  3252. err("FS.trackingDelegate error on read file: " + path);
  3253. }
  3254. }
  3255. try {
  3256. if (FS.trackingDelegate['onOpenFile']) {
  3257. var trackingFlags = 0;
  3258. if ((flags & 2097155) !== 1) {
  3259. trackingFlags |= FS.tracking.openFlags.READ;
  3260. }
  3261. if ((flags & 2097155) !== 0) {
  3262. trackingFlags |= FS.tracking.openFlags.WRITE;
  3263. }
  3264. FS.trackingDelegate['onOpenFile'](path, trackingFlags);
  3265. }
  3266. } catch(e) {
  3267. err("FS.trackingDelegate['onOpenFile']('"+path+"', flags) threw an exception: " + e.message);
  3268. }
  3269. return stream;
  3270. },close:function(stream) {
  3271. if (FS.isClosed(stream)) {
  3272. throw new FS.ErrnoError(8);
  3273. }
  3274. if (stream.getdents) stream.getdents = null; // free readdir state
  3275. try {
  3276. if (stream.stream_ops.close) {
  3277. stream.stream_ops.close(stream);
  3278. }
  3279. } catch (e) {
  3280. throw e;
  3281. } finally {
  3282. FS.closeStream(stream.fd);
  3283. }
  3284. stream.fd = null;
  3285. },isClosed:function(stream) {
  3286. return stream.fd === null;
  3287. },llseek:function(stream, offset, whence) {
  3288. if (FS.isClosed(stream)) {
  3289. throw new FS.ErrnoError(8);
  3290. }
  3291. if (!stream.seekable || !stream.stream_ops.llseek) {
  3292. throw new FS.ErrnoError(70);
  3293. }
  3294. if (whence != 0 && whence != 1 && whence != 2) {
  3295. throw new FS.ErrnoError(28);
  3296. }
  3297. stream.position = stream.stream_ops.llseek(stream, offset, whence);
  3298. stream.ungotten = [];
  3299. return stream.position;
  3300. },read:function(stream, buffer, offset, length, position) {
  3301. if (length < 0 || position < 0) {
  3302. throw new FS.ErrnoError(28);
  3303. }
  3304. if (FS.isClosed(stream)) {
  3305. throw new FS.ErrnoError(8);
  3306. }
  3307. if ((stream.flags & 2097155) === 1) {
  3308. throw new FS.ErrnoError(8);
  3309. }
  3310. if (FS.isDir(stream.node.mode)) {
  3311. throw new FS.ErrnoError(31);
  3312. }
  3313. if (!stream.stream_ops.read) {
  3314. throw new FS.ErrnoError(28);
  3315. }
  3316. var seeking = typeof position !== 'undefined';
  3317. if (!seeking) {
  3318. position = stream.position;
  3319. } else if (!stream.seekable) {
  3320. throw new FS.ErrnoError(70);
  3321. }
  3322. var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
  3323. if (!seeking) stream.position += bytesRead;
  3324. return bytesRead;
  3325. },write:function(stream, buffer, offset, length, position, canOwn) {
  3326. if (length < 0 || position < 0) {
  3327. throw new FS.ErrnoError(28);
  3328. }
  3329. if (FS.isClosed(stream)) {
  3330. throw new FS.ErrnoError(8);
  3331. }
  3332. if ((stream.flags & 2097155) === 0) {
  3333. throw new FS.ErrnoError(8);
  3334. }
  3335. if (FS.isDir(stream.node.mode)) {
  3336. throw new FS.ErrnoError(31);
  3337. }
  3338. if (!stream.stream_ops.write) {
  3339. throw new FS.ErrnoError(28);
  3340. }
  3341. if (stream.seekable && stream.flags & 1024) {
  3342. // seek to the end before writing in append mode
  3343. FS.llseek(stream, 0, 2);
  3344. }
  3345. var seeking = typeof position !== 'undefined';
  3346. if (!seeking) {
  3347. position = stream.position;
  3348. } else if (!stream.seekable) {
  3349. throw new FS.ErrnoError(70);
  3350. }
  3351. var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
  3352. if (!seeking) stream.position += bytesWritten;
  3353. try {
  3354. if (stream.path && FS.trackingDelegate['onWriteToFile']) FS.trackingDelegate['onWriteToFile'](stream.path);
  3355. } catch(e) {
  3356. err("FS.trackingDelegate['onWriteToFile']('"+stream.path+"') threw an exception: " + e.message);
  3357. }
  3358. return bytesWritten;
  3359. },allocate:function(stream, offset, length) {
  3360. if (FS.isClosed(stream)) {
  3361. throw new FS.ErrnoError(8);
  3362. }
  3363. if (offset < 0 || length <= 0) {
  3364. throw new FS.ErrnoError(28);
  3365. }
  3366. if ((stream.flags & 2097155) === 0) {
  3367. throw new FS.ErrnoError(8);
  3368. }
  3369. if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) {
  3370. throw new FS.ErrnoError(43);
  3371. }
  3372. if (!stream.stream_ops.allocate) {
  3373. throw new FS.ErrnoError(138);
  3374. }
  3375. stream.stream_ops.allocate(stream, offset, length);
  3376. },mmap:function(stream, buffer, offset, length, position, prot, flags) {
  3377. // User requests writing to file (prot & PROT_WRITE != 0).
  3378. // Checking if we have permissions to write to the file unless
  3379. // MAP_PRIVATE flag is set. According to POSIX spec it is possible
  3380. // to write to file opened in read-only mode with MAP_PRIVATE flag,
  3381. // as all modifications will be visible only in the memory of
  3382. // the current process.
  3383. if ((prot & 2) !== 0
  3384. && (flags & 2) === 0
  3385. && (stream.flags & 2097155) !== 2) {
  3386. throw new FS.ErrnoError(2);
  3387. }
  3388. if ((stream.flags & 2097155) === 1) {
  3389. throw new FS.ErrnoError(2);
  3390. }
  3391. if (!stream.stream_ops.mmap) {
  3392. throw new FS.ErrnoError(43);
  3393. }
  3394. return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags);
  3395. },msync:function(stream, buffer, offset, length, mmapFlags) {
  3396. if (!stream || !stream.stream_ops.msync) {
  3397. return 0;
  3398. }
  3399. return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags);
  3400. },munmap:function(stream) {
  3401. return 0;
  3402. },ioctl:function(stream, cmd, arg) {
  3403. if (!stream.stream_ops.ioctl) {
  3404. throw new FS.ErrnoError(59);
  3405. }
  3406. return stream.stream_ops.ioctl(stream, cmd, arg);
  3407. },readFile:function(path, opts) {
  3408. opts = opts || {};
  3409. opts.flags = opts.flags || 'r';
  3410. opts.encoding = opts.encoding || 'binary';
  3411. if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
  3412. throw new Error('Invalid encoding type "' + opts.encoding + '"');
  3413. }
  3414. var ret;
  3415. var stream = FS.open(path, opts.flags);
  3416. var stat = FS.stat(path);
  3417. var length = stat.size;
  3418. var buf = new Uint8Array(length);
  3419. FS.read(stream, buf, 0, length, 0);
  3420. if (opts.encoding === 'utf8') {
  3421. ret = UTF8ArrayToString(buf, 0);
  3422. } else if (opts.encoding === 'binary') {
  3423. ret = buf;
  3424. }
  3425. FS.close(stream);
  3426. return ret;
  3427. },writeFile:function(path, data, opts) {
  3428. opts = opts || {};
  3429. opts.flags = opts.flags || 'w';
  3430. var stream = FS.open(path, opts.flags, opts.mode);
  3431. if (typeof data === 'string') {
  3432. var buf = new Uint8Array(lengthBytesUTF8(data)+1);
  3433. var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length);
  3434. FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn);
  3435. } else if (ArrayBuffer.isView(data)) {
  3436. FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
  3437. } else {
  3438. throw new Error('Unsupported data type');
  3439. }
  3440. FS.close(stream);
  3441. },cwd:function() {
  3442. return FS.currentPath;
  3443. },chdir:function(path) {
  3444. var lookup = FS.lookupPath(path, { follow: true });
  3445. if (lookup.node === null) {
  3446. throw new FS.ErrnoError(44);
  3447. }
  3448. if (!FS.isDir(lookup.node.mode)) {
  3449. throw new FS.ErrnoError(54);
  3450. }
  3451. var errCode = FS.nodePermissions(lookup.node, 'x');
  3452. if (errCode) {
  3453. throw new FS.ErrnoError(errCode);
  3454. }
  3455. FS.currentPath = lookup.path;
  3456. },createDefaultDirectories:function() {
  3457. FS.mkdir('/tmp');
  3458. FS.mkdir('/home');
  3459. FS.mkdir('/home/web_user');
  3460. },createDefaultDevices:function() {
  3461. // create /dev
  3462. FS.mkdir('/dev');
  3463. // setup /dev/null
  3464. FS.registerDevice(FS.makedev(1, 3), {
  3465. read: function() { return 0; },
  3466. write: function(stream, buffer, offset, length, pos) { return length; }
  3467. });
  3468. FS.mkdev('/dev/null', FS.makedev(1, 3));
  3469. // setup /dev/tty and /dev/tty1
  3470. // stderr needs to print output using Module['printErr']
  3471. // so we register a second tty just for it.
  3472. TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
  3473. TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
  3474. FS.mkdev('/dev/tty', FS.makedev(5, 0));
  3475. FS.mkdev('/dev/tty1', FS.makedev(6, 0));
  3476. // setup /dev/[u]random
  3477. var random_device;
  3478. if (typeof crypto === 'object' && typeof crypto['getRandomValues'] === 'function') {
  3479. // for modern web browsers
  3480. var randomBuffer = new Uint8Array(1);
  3481. random_device = function() { crypto.getRandomValues(randomBuffer); return randomBuffer[0]; };
  3482. } else
  3483. if (ENVIRONMENT_IS_NODE) {
  3484. // for nodejs with or without crypto support included
  3485. try {
  3486. var crypto_module = require('crypto');
  3487. // nodejs has crypto support
  3488. random_device = function() { return crypto_module['randomBytes'](1)[0]; };
  3489. } catch (e) {
  3490. // nodejs doesn't have crypto support
  3491. }
  3492. } else
  3493. {}
  3494. if (!random_device) {
  3495. // we couldn't find a proper implementation, as Math.random() is not suitable for /dev/random, see emscripten-core/emscripten/pull/7096
  3496. random_device = function() { abort("random_device"); };
  3497. }
  3498. FS.createDevice('/dev', 'random', random_device);
  3499. FS.createDevice('/dev', 'urandom', random_device);
  3500. // we're not going to emulate the actual shm device,
  3501. // just create the tmp dirs that reside in it commonly
  3502. FS.mkdir('/dev/shm');
  3503. FS.mkdir('/dev/shm/tmp');
  3504. },createSpecialDirectories:function() {
  3505. // create /proc/self/fd which allows /proc/self/fd/6 => readlink gives the name of the stream for fd 6 (see test_unistd_ttyname)
  3506. FS.mkdir('/proc');
  3507. FS.mkdir('/proc/self');
  3508. FS.mkdir('/proc/self/fd');
  3509. FS.mount({
  3510. mount: function() {
  3511. var node = FS.createNode('/proc/self', 'fd', 16384 | 511 /* 0777 */, 73);
  3512. node.node_ops = {
  3513. lookup: function(parent, name) {
  3514. var fd = +name;
  3515. var stream = FS.getStream(fd);
  3516. if (!stream) throw new FS.ErrnoError(8);
  3517. var ret = {
  3518. parent: null,
  3519. mount: { mountpoint: 'fake' },
  3520. node_ops: { readlink: function() { return stream.path } }
  3521. };
  3522. ret.parent = ret; // make it look like a simple root node
  3523. return ret;
  3524. }
  3525. };
  3526. return node;
  3527. }
  3528. }, {}, '/proc/self/fd');
  3529. },createStandardStreams:function() {
  3530. // TODO deprecate the old functionality of a single
  3531. // input / output callback and that utilizes FS.createDevice
  3532. // and instead require a unique set of stream ops
  3533.  
  3534. // by default, we symlink the standard streams to the
  3535. // default tty devices. however, if the standard streams
  3536. // have been overwritten we create a unique device for
  3537. // them instead.
  3538. if (Module['stdin']) {
  3539. FS.createDevice('/dev', 'stdin', Module['stdin']);
  3540. } else {
  3541. FS.symlink('/dev/tty', '/dev/stdin');
  3542. }
  3543. if (Module['stdout']) {
  3544. FS.createDevice('/dev', 'stdout', null, Module['stdout']);
  3545. } else {
  3546. FS.symlink('/dev/tty', '/dev/stdout');
  3547. }
  3548. if (Module['stderr']) {
  3549. FS.createDevice('/dev', 'stderr', null, Module['stderr']);
  3550. } else {
  3551. FS.symlink('/dev/tty1', '/dev/stderr');
  3552. }
  3553.  
  3554. // open default streams for the stdin, stdout and stderr devices
  3555. var stdin = FS.open('/dev/stdin', 'r');
  3556. var stdout = FS.open('/dev/stdout', 'w');
  3557. var stderr = FS.open('/dev/stderr', 'w');
  3558. },ensureErrnoError:function() {
  3559. if (FS.ErrnoError) return;
  3560. FS.ErrnoError = /** @this{Object} */ function ErrnoError(errno, node) {
  3561. this.node = node;
  3562. this.setErrno = /** @this{Object} */ function(errno) {
  3563. this.errno = errno;
  3564. };
  3565. this.setErrno(errno);
  3566. this.message = 'FS error';
  3567.  
  3568. };
  3569. FS.ErrnoError.prototype = new Error();
  3570. FS.ErrnoError.prototype.constructor = FS.ErrnoError;
  3571. // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
  3572. [44].forEach(function(code) {
  3573. FS.genericErrors[code] = new FS.ErrnoError(code);
  3574. FS.genericErrors[code].stack = '<generic error, no stack>';
  3575. });
  3576. },staticInit:function() {
  3577. FS.ensureErrnoError();
  3578.  
  3579. FS.nameTable = new Array(4096);
  3580.  
  3581. FS.mount(MEMFS, {}, '/');
  3582.  
  3583. FS.createDefaultDirectories();
  3584. FS.createDefaultDevices();
  3585. FS.createSpecialDirectories();
  3586.  
  3587. FS.filesystems = {
  3588. 'MEMFS': MEMFS,
  3589. };
  3590. },init:function(input, output, error) {
  3591. FS.init.initialized = true;
  3592.  
  3593. FS.ensureErrnoError();
  3594.  
  3595. // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
  3596. Module['stdin'] = input || Module['stdin'];
  3597. Module['stdout'] = output || Module['stdout'];
  3598. Module['stderr'] = error || Module['stderr'];
  3599.  
  3600. FS.createStandardStreams();
  3601. },quit:function() {
  3602. FS.init.initialized = false;
  3603. // force-flush all streams, so we get musl std streams printed out
  3604. var fflush = Module['_fflush'];
  3605. if (fflush) fflush(0);
  3606. // close all of our streams
  3607. for (var i = 0; i < FS.streams.length; i++) {
  3608. var stream = FS.streams[i];
  3609. if (!stream) {
  3610. continue;
  3611. }
  3612. FS.close(stream);
  3613. }
  3614. },getMode:function(canRead, canWrite) {
  3615. var mode = 0;
  3616. if (canRead) mode |= 292 | 73;
  3617. if (canWrite) mode |= 146;
  3618. return mode;
  3619. },joinPath:function(parts, forceRelative) {
  3620. var path = PATH.join.apply(null, parts);
  3621. if (forceRelative && path[0] == '/') path = path.substr(1);
  3622. return path;
  3623. },absolutePath:function(relative, base) {
  3624. return PATH_FS.resolve(base, relative);
  3625. },standardizePath:function(path) {
  3626. return PATH.normalize(path);
  3627. },findObject:function(path, dontResolveLastLink) {
  3628. var ret = FS.analyzePath(path, dontResolveLastLink);
  3629. if (ret.exists) {
  3630. return ret.object;
  3631. } else {
  3632. setErrNo(ret.error);
  3633. return null;
  3634. }
  3635. },analyzePath:function(path, dontResolveLastLink) {
  3636. // operate from within the context of the symlink's target
  3637. try {
  3638. var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
  3639. path = lookup.path;
  3640. } catch (e) {
  3641. }
  3642. var ret = {
  3643. isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
  3644. parentExists: false, parentPath: null, parentObject: null
  3645. };
  3646. try {
  3647. var lookup = FS.lookupPath(path, { parent: true });
  3648. ret.parentExists = true;
  3649. ret.parentPath = lookup.path;
  3650. ret.parentObject = lookup.node;
  3651. ret.name = PATH.basename(path);
  3652. lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
  3653. ret.exists = true;
  3654. ret.path = lookup.path;
  3655. ret.object = lookup.node;
  3656. ret.name = lookup.node.name;
  3657. ret.isRoot = lookup.path === '/';
  3658. } catch (e) {
  3659. ret.error = e.errno;
  3660. };
  3661. return ret;
  3662. },createFolder:function(parent, name, canRead, canWrite) {
  3663. var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
  3664. var mode = FS.getMode(canRead, canWrite);
  3665. return FS.mkdir(path, mode);
  3666. },createPath:function(parent, path, canRead, canWrite) {
  3667. parent = typeof parent === 'string' ? parent : FS.getPath(parent);
  3668. var parts = path.split('/').reverse();
  3669. while (parts.length) {
  3670. var part = parts.pop();
  3671. if (!part) continue;
  3672. var current = PATH.join2(parent, part);
  3673. try {
  3674. FS.mkdir(current);
  3675. } catch (e) {
  3676. // ignore EEXIST
  3677. }
  3678. parent = current;
  3679. }
  3680. return current;
  3681. },createFile:function(parent, name, properties, canRead, canWrite) {
  3682. var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
  3683. var mode = FS.getMode(canRead, canWrite);
  3684. return FS.create(path, mode);
  3685. },createDataFile:function(parent, name, data, canRead, canWrite, canOwn) {
  3686. var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent;
  3687. var mode = FS.getMode(canRead, canWrite);
  3688. var node = FS.create(path, mode);
  3689. if (data) {
  3690. if (typeof data === 'string') {
  3691. var arr = new Array(data.length);
  3692. for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
  3693. data = arr;
  3694. }
  3695. // make sure we can write to the file
  3696. FS.chmod(node, mode | 146);
  3697. var stream = FS.open(node, 'w');
  3698. FS.write(stream, data, 0, data.length, 0, canOwn);
  3699. FS.close(stream);
  3700. FS.chmod(node, mode);
  3701. }
  3702. return node;
  3703. },createDevice:function(parent, name, input, output) {
  3704. var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
  3705. var mode = FS.getMode(!!input, !!output);
  3706. if (!FS.createDevice.major) FS.createDevice.major = 64;
  3707. var dev = FS.makedev(FS.createDevice.major++, 0);
  3708. // Create a fake device that a set of stream ops to emulate
  3709. // the old behavior.
  3710. FS.registerDevice(dev, {
  3711. open: function(stream) {
  3712. stream.seekable = false;
  3713. },
  3714. close: function(stream) {
  3715. // flush any pending line data
  3716. if (output && output.buffer && output.buffer.length) {
  3717. output(10);
  3718. }
  3719. },
  3720. read: function(stream, buffer, offset, length, pos /* ignored */) {
  3721. var bytesRead = 0;
  3722. for (var i = 0; i < length; i++) {
  3723. var result;
  3724. try {
  3725. result = input();
  3726. } catch (e) {
  3727. throw new FS.ErrnoError(29);
  3728. }
  3729. if (result === undefined && bytesRead === 0) {
  3730. throw new FS.ErrnoError(6);
  3731. }
  3732. if (result === null || result === undefined) break;
  3733. bytesRead++;
  3734. buffer[offset+i] = result;
  3735. }
  3736. if (bytesRead) {
  3737. stream.node.timestamp = Date.now();
  3738. }
  3739. return bytesRead;
  3740. },
  3741. write: function(stream, buffer, offset, length, pos) {
  3742. for (var i = 0; i < length; i++) {
  3743. try {
  3744. output(buffer[offset+i]);
  3745. } catch (e) {
  3746. throw new FS.ErrnoError(29);
  3747. }
  3748. }
  3749. if (length) {
  3750. stream.node.timestamp = Date.now();
  3751. }
  3752. return i;
  3753. }
  3754. });
  3755. return FS.mkdev(path, mode, dev);
  3756. },createLink:function(parent, name, target, canRead, canWrite) {
  3757. var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
  3758. return FS.symlink(target, path);
  3759. },forceLoadFile:function(obj) {
  3760. if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
  3761. var success = true;
  3762. if (typeof XMLHttpRequest !== 'undefined') {
  3763. 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.");
  3764. } else if (read_) {
  3765. // Command-line.
  3766. try {
  3767. // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
  3768. // read() will try to parse UTF8.
  3769. obj.contents = intArrayFromString(read_(obj.url), true);
  3770. obj.usedBytes = obj.contents.length;
  3771. } catch (e) {
  3772. success = false;
  3773. }
  3774. } else {
  3775. throw new Error('Cannot load without read() or XMLHttpRequest.');
  3776. }
  3777. if (!success) setErrNo(29);
  3778. return success;
  3779. },createLazyFile:function(parent, name, url, canRead, canWrite) {
  3780. // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
  3781. /** @constructor */
  3782. function LazyUint8Array() {
  3783. this.lengthKnown = false;
  3784. this.chunks = []; // Loaded chunks. Index is the chunk number
  3785. }
  3786. LazyUint8Array.prototype.get = /** @this{Object} */ function LazyUint8Array_get(idx) {
  3787. if (idx > this.length-1 || idx < 0) {
  3788. return undefined;
  3789. }
  3790. var chunkOffset = idx % this.chunkSize;
  3791. var chunkNum = (idx / this.chunkSize)|0;
  3792. return this.getter(chunkNum)[chunkOffset];
  3793. };
  3794. LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
  3795. this.getter = getter;
  3796. };
  3797. LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
  3798. // Find length
  3799. var xhr = new XMLHttpRequest();
  3800. xhr.open('HEAD', url, false);
  3801. xhr.send(null);
  3802. if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
  3803. var datalength = Number(xhr.getResponseHeader("Content-length"));
  3804. var header;
  3805. var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
  3806. var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip";
  3807.  
  3808. var chunkSize = 1024*1024; // Chunk size in bytes
  3809.  
  3810. if (!hasByteServing) chunkSize = datalength;
  3811.  
  3812. // Function to get a range from the remote URL.
  3813. var doXHR = (function(from, to) {
  3814. if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
  3815. if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
  3816.  
  3817. // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
  3818. var xhr = new XMLHttpRequest();
  3819. xhr.open('GET', url, false);
  3820. if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
  3821.  
  3822. // Some hints to the browser that we want binary data.
  3823. if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer';
  3824. if (xhr.overrideMimeType) {
  3825. xhr.overrideMimeType('text/plain; charset=x-user-defined');
  3826. }
  3827.  
  3828. xhr.send(null);
  3829. if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
  3830. if (xhr.response !== undefined) {
  3831. return new Uint8Array(/** @type{Array<number>} */(xhr.response || []));
  3832. } else {
  3833. return intArrayFromString(xhr.responseText || '', true);
  3834. }
  3835. });
  3836. var lazyArray = this;
  3837. lazyArray.setDataGetter(function(chunkNum) {
  3838. var start = chunkNum * chunkSize;
  3839. var end = (chunkNum+1) * chunkSize - 1; // including this byte
  3840. end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
  3841. if (typeof(lazyArray.chunks[chunkNum]) === "undefined") {
  3842. lazyArray.chunks[chunkNum] = doXHR(start, end);
  3843. }
  3844. if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!");
  3845. return lazyArray.chunks[chunkNum];
  3846. });
  3847.  
  3848. if (usesGzip || !datalength) {
  3849. // if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length
  3850. chunkSize = datalength = 1; // this will force getter(0)/doXHR do download the whole file
  3851. datalength = this.getter(0).length;
  3852. chunkSize = datalength;
  3853. out("LazyFiles on gzip forces download of the whole file when length is accessed");
  3854. }
  3855.  
  3856. this._length = datalength;
  3857. this._chunkSize = chunkSize;
  3858. this.lengthKnown = true;
  3859. };
  3860. if (typeof XMLHttpRequest !== 'undefined') {
  3861. if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
  3862. var lazyArray = new LazyUint8Array();
  3863. Object.defineProperties(lazyArray, {
  3864. length: {
  3865. get: /** @this{Object} */ function() {
  3866. if(!this.lengthKnown) {
  3867. this.cacheLength();
  3868. }
  3869. return this._length;
  3870. }
  3871. },
  3872. chunkSize: {
  3873. get: /** @this{Object} */ function() {
  3874. if(!this.lengthKnown) {
  3875. this.cacheLength();
  3876. }
  3877. return this._chunkSize;
  3878. }
  3879. }
  3880. });
  3881.  
  3882. var properties = { isDevice: false, contents: lazyArray };
  3883. } else {
  3884. var properties = { isDevice: false, url: url };
  3885. }
  3886.  
  3887. var node = FS.createFile(parent, name, properties, canRead, canWrite);
  3888. // This is a total hack, but I want to get this lazy file code out of the
  3889. // core of MEMFS. If we want to keep this lazy file concept I feel it should
  3890. // be its own thin LAZYFS proxying calls to MEMFS.
  3891. if (properties.contents) {
  3892. node.contents = properties.contents;
  3893. } else if (properties.url) {
  3894. node.contents = null;
  3895. node.url = properties.url;
  3896. }
  3897. // Add a function that defers querying the file size until it is asked the first time.
  3898. Object.defineProperties(node, {
  3899. usedBytes: {
  3900. get: /** @this {FSNode} */ function() { return this.contents.length; }
  3901. }
  3902. });
  3903. // override each stream op with one that tries to force load the lazy file first
  3904. var stream_ops = {};
  3905. var keys = Object.keys(node.stream_ops);
  3906. keys.forEach(function(key) {
  3907. var fn = node.stream_ops[key];
  3908. stream_ops[key] = function forceLoadLazyFile() {
  3909. if (!FS.forceLoadFile(node)) {
  3910. throw new FS.ErrnoError(29);
  3911. }
  3912. return fn.apply(null, arguments);
  3913. };
  3914. });
  3915. // use a custom read function
  3916. stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) {
  3917. if (!FS.forceLoadFile(node)) {
  3918. throw new FS.ErrnoError(29);
  3919. }
  3920. var contents = stream.node.contents;
  3921. if (position >= contents.length)
  3922. return 0;
  3923. var size = Math.min(contents.length - position, length);
  3924. if (contents.slice) { // normal array
  3925. for (var i = 0; i < size; i++) {
  3926. buffer[offset + i] = contents[position + i];
  3927. }
  3928. } else {
  3929. for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
  3930. buffer[offset + i] = contents.get(position + i);
  3931. }
  3932. }
  3933. return size;
  3934. };
  3935. node.stream_ops = stream_ops;
  3936. return node;
  3937. },createPreloadedFile:function(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) {
  3938. Browser.init(); // XXX perhaps this method should move onto Browser?
  3939. // TODO we should allow people to just pass in a complete filename instead
  3940. // of parent and name being that we just join them anyways
  3941. var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;
  3942. var dep = getUniqueRunDependency('cp ' + fullname); // might have several active requests for the same fullname
  3943. function processData(byteArray) {
  3944. function finish(byteArray) {
  3945. if (preFinish) preFinish();
  3946. if (!dontCreateFile) {
  3947. FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
  3948. }
  3949. if (onload) onload();
  3950. removeRunDependency(dep);
  3951. }
  3952. var handled = false;
  3953. Module['preloadPlugins'].forEach(function(plugin) {
  3954. if (handled) return;
  3955. if (plugin['canHandle'](fullname)) {
  3956. plugin['handle'](byteArray, fullname, finish, function() {
  3957. if (onerror) onerror();
  3958. removeRunDependency(dep);
  3959. });
  3960. handled = true;
  3961. }
  3962. });
  3963. if (!handled) finish(byteArray);
  3964. }
  3965. addRunDependency(dep);
  3966. if (typeof url == 'string') {
  3967. Browser.asyncLoad(url, function(byteArray) {
  3968. processData(byteArray);
  3969. }, onerror);
  3970. } else {
  3971. processData(url);
  3972. }
  3973. },indexedDB:function() {
  3974. return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
  3975. },DB_NAME:function() {
  3976. return 'EM_FS_' + window.location.pathname;
  3977. },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function(paths, onload, onerror) {
  3978. onload = onload || function(){};
  3979. onerror = onerror || function(){};
  3980. var indexedDB = FS.indexedDB();
  3981. try {
  3982. var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
  3983. } catch (e) {
  3984. return onerror(e);
  3985. }
  3986. openRequest.onupgradeneeded = function openRequest_onupgradeneeded() {
  3987. out('creating db');
  3988. var db = openRequest.result;
  3989. db.createObjectStore(FS.DB_STORE_NAME);
  3990. };
  3991. openRequest.onsuccess = function openRequest_onsuccess() {
  3992. var db = openRequest.result;
  3993. var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');
  3994. var files = transaction.objectStore(FS.DB_STORE_NAME);
  3995. var ok = 0, fail = 0, total = paths.length;
  3996. function finish() {
  3997. if (fail == 0) onload(); else onerror();
  3998. }
  3999. paths.forEach(function(path) {
  4000. var putRequest = files.put(FS.analyzePath(path).object.contents, path);
  4001. putRequest.onsuccess = function putRequest_onsuccess() { ok++; if (ok + fail == total) finish() };
  4002. putRequest.onerror = function putRequest_onerror() { fail++; if (ok + fail == total) finish() };
  4003. });
  4004. transaction.onerror = onerror;
  4005. };
  4006. openRequest.onerror = onerror;
  4007. },loadFilesFromDB:function(paths, onload, onerror) {
  4008. onload = onload || function(){};
  4009. onerror = onerror || function(){};
  4010. var indexedDB = FS.indexedDB();
  4011. try {
  4012. var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
  4013. } catch (e) {
  4014. return onerror(e);
  4015. }
  4016. openRequest.onupgradeneeded = onerror; // no database to load from
  4017. openRequest.onsuccess = function openRequest_onsuccess() {
  4018. var db = openRequest.result;
  4019. try {
  4020. var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');
  4021. } catch(e) {
  4022. onerror(e);
  4023. return;
  4024. }
  4025. var files = transaction.objectStore(FS.DB_STORE_NAME);
  4026. var ok = 0, fail = 0, total = paths.length;
  4027. function finish() {
  4028. if (fail == 0) onload(); else onerror();
  4029. }
  4030. paths.forEach(function(path) {
  4031. var getRequest = files.get(path);
  4032. getRequest.onsuccess = function getRequest_onsuccess() {
  4033. if (FS.analyzePath(path).exists) {
  4034. FS.unlink(path);
  4035. }
  4036. FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
  4037. ok++;
  4038. if (ok + fail == total) finish();
  4039. };
  4040. getRequest.onerror = function getRequest_onerror() { fail++; if (ok + fail == total) finish() };
  4041. });
  4042. transaction.onerror = onerror;
  4043. };
  4044. openRequest.onerror = onerror;
  4045. }};var SYSCALLS={mappings:{},DEFAULT_POLLMASK:5,umask:511,calculateAt:function(dirfd, path) {
  4046. if (path[0] !== '/') {
  4047. // relative path
  4048. var dir;
  4049. if (dirfd === -100) {
  4050. dir = FS.cwd();
  4051. } else {
  4052. var dirstream = FS.getStream(dirfd);
  4053. if (!dirstream) throw new FS.ErrnoError(8);
  4054. dir = dirstream.path;
  4055. }
  4056. path = PATH.join2(dir, path);
  4057. }
  4058. return path;
  4059. },doStat:function(func, path, buf) {
  4060. try {
  4061. var stat = func(path);
  4062. } catch (e) {
  4063. if (e && e.node && PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))) {
  4064. // an error occurred while trying to look up the path; we should just report ENOTDIR
  4065. return -54;
  4066. }
  4067. throw e;
  4068. }
  4069. HEAP32[((buf)>>2)]=stat.dev;
  4070. HEAP32[(((buf)+(4))>>2)]=0;
  4071. HEAP32[(((buf)+(8))>>2)]=stat.ino;
  4072. HEAP32[(((buf)+(12))>>2)]=stat.mode;
  4073. HEAP32[(((buf)+(16))>>2)]=stat.nlink;
  4074. HEAP32[(((buf)+(20))>>2)]=stat.uid;
  4075. HEAP32[(((buf)+(24))>>2)]=stat.gid;
  4076. HEAP32[(((buf)+(28))>>2)]=stat.rdev;
  4077. HEAP32[(((buf)+(32))>>2)]=0;
  4078. (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]);
  4079. HEAP32[(((buf)+(48))>>2)]=4096;
  4080. HEAP32[(((buf)+(52))>>2)]=stat.blocks;
  4081. HEAP32[(((buf)+(56))>>2)]=(stat.atime.getTime() / 1000)|0;
  4082. HEAP32[(((buf)+(60))>>2)]=0;
  4083. HEAP32[(((buf)+(64))>>2)]=(stat.mtime.getTime() / 1000)|0;
  4084. HEAP32[(((buf)+(68))>>2)]=0;
  4085. HEAP32[(((buf)+(72))>>2)]=(stat.ctime.getTime() / 1000)|0;
  4086. HEAP32[(((buf)+(76))>>2)]=0;
  4087. (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]);
  4088. return 0;
  4089. },doMsync:function(addr, stream, len, flags, offset) {
  4090. var buffer = HEAPU8.slice(addr, addr + len);
  4091. FS.msync(stream, buffer, offset, len, flags);
  4092. },doMkdir:function(path, mode) {
  4093. // remove a trailing slash, if one - /a/b/ has basename of '', but
  4094. // we want to create b in the context of this function
  4095. path = PATH.normalize(path);
  4096. if (path[path.length-1] === '/') path = path.substr(0, path.length-1);
  4097. FS.mkdir(path, mode, 0);
  4098. return 0;
  4099. },doMknod:function(path, mode, dev) {
  4100. // we don't want this in the JS API as it uses mknod to create all nodes.
  4101. switch (mode & 61440) {
  4102. case 32768:
  4103. case 8192:
  4104. case 24576:
  4105. case 4096:
  4106. case 49152:
  4107. break;
  4108. default: return -28;
  4109. }
  4110. FS.mknod(path, mode, dev);
  4111. return 0;
  4112. },doReadlink:function(path, buf, bufsize) {
  4113. if (bufsize <= 0) return -28;
  4114. var ret = FS.readlink(path);
  4115.  
  4116. var len = Math.min(bufsize, lengthBytesUTF8(ret));
  4117. var endChar = HEAP8[buf+len];
  4118. stringToUTF8(ret, buf, bufsize+1);
  4119. // readlink is one of the rare functions that write out a C string, but does never append a null to the output buffer(!)
  4120. // stringToUTF8() always appends a null byte, so restore the character under the null byte after the write.
  4121. HEAP8[buf+len] = endChar;
  4122.  
  4123. return len;
  4124. },doAccess:function(path, amode) {
  4125. if (amode & ~7) {
  4126. // need a valid mode
  4127. return -28;
  4128. }
  4129. var node;
  4130. var lookup = FS.lookupPath(path, { follow: true });
  4131. node = lookup.node;
  4132. if (!node) {
  4133. return -44;
  4134. }
  4135. var perms = '';
  4136. if (amode & 4) perms += 'r';
  4137. if (amode & 2) perms += 'w';
  4138. if (amode & 1) perms += 'x';
  4139. if (perms /* otherwise, they've just passed F_OK */ && FS.nodePermissions(node, perms)) {
  4140. return -2;
  4141. }
  4142. return 0;
  4143. },doDup:function(path, flags, suggestFD) {
  4144. var suggest = FS.getStream(suggestFD);
  4145. if (suggest) FS.close(suggest);
  4146. return FS.open(path, flags, 0, suggestFD, suggestFD).fd;
  4147. },doReadv:function(stream, iov, iovcnt, offset) {
  4148. var ret = 0;
  4149. for (var i = 0; i < iovcnt; i++) {
  4150. var ptr = HEAP32[(((iov)+(i*8))>>2)];
  4151. var len = HEAP32[(((iov)+(i*8 + 4))>>2)];
  4152. var curr = FS.read(stream, HEAP8,ptr, len, offset);
  4153. if (curr < 0) return -1;
  4154. ret += curr;
  4155. if (curr < len) break; // nothing more to read
  4156. }
  4157. return ret;
  4158. },doWritev:function(stream, iov, iovcnt, offset) {
  4159. var ret = 0;
  4160. for (var i = 0; i < iovcnt; i++) {
  4161. var ptr = HEAP32[(((iov)+(i*8))>>2)];
  4162. var len = HEAP32[(((iov)+(i*8 + 4))>>2)];
  4163. var curr = FS.write(stream, HEAP8,ptr, len, offset);
  4164. if (curr < 0) return -1;
  4165. ret += curr;
  4166. }
  4167. return ret;
  4168. },varargs:undefined,get:function() {
  4169. SYSCALLS.varargs += 4;
  4170. var ret = HEAP32[(((SYSCALLS.varargs)-(4))>>2)];
  4171. return ret;
  4172. },getStr:function(ptr) {
  4173. var ret = UTF8ToString(ptr);
  4174. return ret;
  4175. },getStreamFromFD:function(fd) {
  4176. var stream = FS.getStream(fd);
  4177. if (!stream) throw new FS.ErrnoError(8);
  4178. return stream;
  4179. },get64:function(low, high) {
  4180. return low;
  4181. }};function ___sys_access(path, amode) {try {
  4182.  
  4183. path = SYSCALLS.getStr(path);
  4184. return SYSCALLS.doAccess(path, amode);
  4185. } catch (e) {
  4186. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  4187. return -e.errno;
  4188. }
  4189. }
  4190.  
  4191. function ___sys_dup(fd) {try {
  4192.  
  4193. var old = SYSCALLS.getStreamFromFD(fd);
  4194. return FS.open(old.path, old.flags, 0).fd;
  4195. } catch (e) {
  4196. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  4197. return -e.errno;
  4198. }
  4199. }
  4200.  
  4201. function ___sys_fcntl64(fd, cmd, varargs) {SYSCALLS.varargs = varargs;
  4202. try {
  4203.  
  4204. var stream = SYSCALLS.getStreamFromFD(fd);
  4205. switch (cmd) {
  4206. case 0: {
  4207. var arg = SYSCALLS.get();
  4208. if (arg < 0) {
  4209. return -28;
  4210. }
  4211. var newStream;
  4212. newStream = FS.open(stream.path, stream.flags, 0, arg);
  4213. return newStream.fd;
  4214. }
  4215. case 1:
  4216. case 2:
  4217. return 0; // FD_CLOEXEC makes no sense for a single process.
  4218. case 3:
  4219. return stream.flags;
  4220. case 4: {
  4221. var arg = SYSCALLS.get();
  4222. stream.flags |= arg;
  4223. return 0;
  4224. }
  4225. case 12:
  4226. /* case 12: Currently in musl F_GETLK64 has same value as F_GETLK, so omitted to avoid duplicate case blocks. If that changes, uncomment this */ {
  4227.  
  4228. var arg = SYSCALLS.get();
  4229. var offset = 0;
  4230. // We're always unlocked.
  4231. HEAP16[(((arg)+(offset))>>1)]=2;
  4232. return 0;
  4233. }
  4234. case 13:
  4235. case 14:
  4236. /* case 13: Currently in musl F_SETLK64 has same value as F_SETLK, so omitted to avoid duplicate case blocks. If that changes, uncomment this */
  4237. /* case 14: Currently in musl F_SETLKW64 has same value as F_SETLKW, so omitted to avoid duplicate case blocks. If that changes, uncomment this */
  4238.  
  4239.  
  4240. return 0; // Pretend that the locking is successful.
  4241. case 16:
  4242. case 8:
  4243. return -28; // These are for sockets. We don't have them fully implemented yet.
  4244. case 9:
  4245. // 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.
  4246. setErrNo(28);
  4247. return -1;
  4248. default: {
  4249. return -28;
  4250. }
  4251. }
  4252. } catch (e) {
  4253. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  4254. return -e.errno;
  4255. }
  4256. }
  4257.  
  4258. function ___sys_getcwd(buf, size) {try {
  4259.  
  4260. if (size === 0) return -28;
  4261. var cwd = FS.cwd();
  4262. var cwdLengthInBytes = lengthBytesUTF8(cwd);
  4263. if (size < cwdLengthInBytes + 1) return -68;
  4264. stringToUTF8(cwd, buf, size);
  4265. return buf;
  4266. } catch (e) {
  4267. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  4268. return -e.errno;
  4269. }
  4270. }
  4271.  
  4272. function ___sys_getdents64(fd, dirp, count) {try {
  4273.  
  4274. var stream = SYSCALLS.getStreamFromFD(fd)
  4275. if (!stream.getdents) {
  4276. stream.getdents = FS.readdir(stream.path);
  4277. }
  4278.  
  4279. var struct_size = 280;
  4280. var pos = 0;
  4281. var off = FS.llseek(stream, 0, 1);
  4282.  
  4283. var idx = Math.floor(off / struct_size);
  4284.  
  4285. while (idx < stream.getdents.length && pos + struct_size <= count) {
  4286. var id;
  4287. var type;
  4288. var name = stream.getdents[idx];
  4289. if (name[0] === '.') {
  4290. id = 1;
  4291. type = 4; // DT_DIR
  4292. } else {
  4293. var child = FS.lookupNode(stream.node, name);
  4294. id = child.id;
  4295. type = FS.isChrdev(child.mode) ? 2 : // DT_CHR, character device.
  4296. FS.isDir(child.mode) ? 4 : // DT_DIR, directory.
  4297. FS.isLink(child.mode) ? 10 : // DT_LNK, symbolic link.
  4298. 8; // DT_REG, regular file.
  4299. }
  4300. (tempI64 = [id>>>0,(tempDouble=id,(+(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[((dirp + pos)>>2)]=tempI64[0],HEAP32[(((dirp + pos)+(4))>>2)]=tempI64[1]);
  4301. (tempI64 = [(idx + 1) * struct_size>>>0,(tempDouble=(idx + 1) * struct_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[(((dirp + pos)+(8))>>2)]=tempI64[0],HEAP32[(((dirp + pos)+(12))>>2)]=tempI64[1]);
  4302. HEAP16[(((dirp + pos)+(16))>>1)]=280;
  4303. HEAP8[(((dirp + pos)+(18))>>0)]=type;
  4304. stringToUTF8(name, dirp + pos + 19, 256);
  4305. pos += struct_size;
  4306. idx += 1;
  4307. }
  4308. FS.llseek(stream, idx * struct_size, 0);
  4309. return pos;
  4310. } catch (e) {
  4311. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  4312. return -e.errno;
  4313. }
  4314. }
  4315.  
  4316. function ___sys_getpid() {
  4317. return 42;
  4318. }
  4319.  
  4320.  
  4321. function ___sys_getegid32() {
  4322. return 0;
  4323. }function ___sys_getuid32(
  4324. ) {
  4325. return ___sys_getegid32();
  4326. }
  4327.  
  4328. function ___sys_ioctl(fd, op, varargs) {SYSCALLS.varargs = varargs;
  4329. try {
  4330.  
  4331. var stream = SYSCALLS.getStreamFromFD(fd);
  4332. switch (op) {
  4333. case 21509:
  4334. case 21505: {
  4335. if (!stream.tty) return -59;
  4336. return 0;
  4337. }
  4338. case 21510:
  4339. case 21511:
  4340. case 21512:
  4341. case 21506:
  4342. case 21507:
  4343. case 21508: {
  4344. if (!stream.tty) return -59;
  4345. return 0; // no-op, not actually adjusting terminal settings
  4346. }
  4347. case 21519: {
  4348. if (!stream.tty) return -59;
  4349. var argp = SYSCALLS.get();
  4350. HEAP32[((argp)>>2)]=0;
  4351. return 0;
  4352. }
  4353. case 21520: {
  4354. if (!stream.tty) return -59;
  4355. return -28; // not supported
  4356. }
  4357. case 21531: {
  4358. var argp = SYSCALLS.get();
  4359. return FS.ioctl(stream, op, argp);
  4360. }
  4361. case 21523: {
  4362. // TODO: in theory we should write to the winsize struct that gets
  4363. // passed in, but for now musl doesn't read anything on it
  4364. if (!stream.tty) return -59;
  4365. return 0;
  4366. }
  4367. case 21524: {
  4368. // TODO: technically, this ioctl call should change the window size.
  4369. // but, since emscripten doesn't have any concept of a terminal window
  4370. // yet, we'll just silently throw it away as we do TIOCGWINSZ
  4371. if (!stream.tty) return -59;
  4372. return 0;
  4373. }
  4374. default: abort('bad ioctl syscall ' + op);
  4375. }
  4376. } catch (e) {
  4377. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  4378. return -e.errno;
  4379. }
  4380. }
  4381.  
  4382. function ___sys_lstat64(path, buf) {try {
  4383.  
  4384. path = SYSCALLS.getStr(path);
  4385. return SYSCALLS.doStat(FS.lstat, path, buf);
  4386. } catch (e) {
  4387. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  4388. return -e.errno;
  4389. }
  4390. }
  4391.  
  4392. function ___sys_open(path, flags, varargs) {SYSCALLS.varargs = varargs;
  4393. try {
  4394.  
  4395. var pathname = SYSCALLS.getStr(path);
  4396. var mode = SYSCALLS.get();
  4397. var stream = FS.open(pathname, flags, mode);
  4398. return stream.fd;
  4399. } catch (e) {
  4400. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  4401. return -e.errno;
  4402. }
  4403. }
  4404.  
  4405.  
  4406.  
  4407. var ERRNO_CODES={EPERM:63,ENOENT:44,ESRCH:71,EINTR:27,EIO:29,ENXIO:60,E2BIG:1,ENOEXEC:45,EBADF:8,ECHILD:12,EAGAIN:6,EWOULDBLOCK:6,ENOMEM:48,EACCES:2,EFAULT:21,ENOTBLK:105,EBUSY:10,EEXIST:20,EXDEV:75,ENODEV:43,ENOTDIR:54,EISDIR:31,EINVAL:28,ENFILE:41,EMFILE:33,ENOTTY:59,ETXTBSY:74,EFBIG:22,ENOSPC:51,ESPIPE:70,EROFS:69,EMLINK:34,EPIPE:64,EDOM:18,ERANGE:68,ENOMSG:49,EIDRM:24,ECHRNG:106,EL2NSYNC:156,EL3HLT:107,EL3RST:108,ELNRNG:109,EUNATCH:110,ENOCSI:111,EL2HLT:112,EDEADLK:16,ENOLCK:46,EBADE:113,EBADR:114,EXFULL:115,ENOANO:104,EBADRQC:103,EBADSLT:102,EDEADLOCK:16,EBFONT:101,ENOSTR:100,ENODATA:116,ETIME:117,ENOSR:118,ENONET:119,ENOPKG:120,EREMOTE:121,ENOLINK:47,EADV:122,ESRMNT:123,ECOMM:124,EPROTO:65,EMULTIHOP:36,EDOTDOT:125,EBADMSG:9,ENOTUNIQ:126,EBADFD:127,EREMCHG:128,ELIBACC:129,ELIBBAD:130,ELIBSCN:131,ELIBMAX:132,ELIBEXEC:133,ENOSYS:52,ENOTEMPTY:55,ENAMETOOLONG:37,ELOOP:32,EOPNOTSUPP:138,EPFNOSUPPORT:139,ECONNRESET:15,ENOBUFS:42,EAFNOSUPPORT:5,EPROTOTYPE:67,ENOTSOCK:57,ENOPROTOOPT:50,ESHUTDOWN:140,ECONNREFUSED:14,EADDRINUSE:3,ECONNABORTED:13,ENETUNREACH:40,ENETDOWN:38,ETIMEDOUT:73,EHOSTDOWN:142,EHOSTUNREACH:23,EINPROGRESS:26,EALREADY:7,EDESTADDRREQ:17,EMSGSIZE:35,EPROTONOSUPPORT:66,ESOCKTNOSUPPORT:137,EADDRNOTAVAIL:4,ENETRESET:39,EISCONN:30,ENOTCONN:53,ETOOMANYREFS:141,EUSERS:136,EDQUOT:19,ESTALE:72,ENOTSUP:138,ENOMEDIUM:148,EILSEQ:25,EOVERFLOW:61,ECANCELED:11,ENOTRECOVERABLE:56,EOWNERDEAD:62,ESTRPIPE:135};var PIPEFS={BUCKET_BUFFER_SIZE:8192,mount:function (mount) {
  4408. // Do not pollute the real root directory or its child nodes with pipes
  4409. // Looks like it is OK to create another pseudo-root node not linked to the FS.root hierarchy this way
  4410. return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
  4411. },createPipe:function () {
  4412. var pipe = {
  4413. buckets: []
  4414. };
  4415.  
  4416. pipe.buckets.push({
  4417. buffer: new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),
  4418. offset: 0,
  4419. roffset: 0
  4420. });
  4421.  
  4422. var rName = PIPEFS.nextname();
  4423. var wName = PIPEFS.nextname();
  4424. var rNode = FS.createNode(PIPEFS.root, rName, 4096, 0);
  4425. var wNode = FS.createNode(PIPEFS.root, wName, 4096, 0);
  4426.  
  4427. rNode.pipe = pipe;
  4428. wNode.pipe = pipe;
  4429.  
  4430. var readableStream = FS.createStream({
  4431. path: rName,
  4432. node: rNode,
  4433. flags: FS.modeStringToFlags('r'),
  4434. seekable: false,
  4435. stream_ops: PIPEFS.stream_ops
  4436. });
  4437. rNode.stream = readableStream;
  4438.  
  4439. var writableStream = FS.createStream({
  4440. path: wName,
  4441. node: wNode,
  4442. flags: FS.modeStringToFlags('w'),
  4443. seekable: false,
  4444. stream_ops: PIPEFS.stream_ops
  4445. });
  4446. wNode.stream = writableStream;
  4447.  
  4448. return {
  4449. readable_fd: readableStream.fd,
  4450. writable_fd: writableStream.fd
  4451. };
  4452. },stream_ops:{poll:function (stream) {
  4453. var pipe = stream.node.pipe;
  4454.  
  4455. if ((stream.flags & 2097155) === 1) {
  4456. return (256 | 4);
  4457. } else {
  4458. if (pipe.buckets.length > 0) {
  4459. for (var i = 0; i < pipe.buckets.length; i++) {
  4460. var bucket = pipe.buckets[i];
  4461. if (bucket.offset - bucket.roffset > 0) {
  4462. return (64 | 1);
  4463. }
  4464. }
  4465. }
  4466. }
  4467.  
  4468. return 0;
  4469. },ioctl:function (stream, request, varargs) {
  4470. return ERRNO_CODES.EINVAL;
  4471. },fsync:function (stream) {
  4472. return ERRNO_CODES.EINVAL;
  4473. },read:function (stream, buffer, offset, length, position /* ignored */) {
  4474. var pipe = stream.node.pipe;
  4475. var currentLength = 0;
  4476.  
  4477. for (var i = 0; i < pipe.buckets.length; i++) {
  4478. var bucket = pipe.buckets[i];
  4479. currentLength += bucket.offset - bucket.roffset;
  4480. }
  4481.  
  4482. assert(buffer instanceof ArrayBuffer || ArrayBuffer.isView(buffer));
  4483. var data = buffer.subarray(offset, offset + length);
  4484.  
  4485. if (length <= 0) {
  4486. return 0;
  4487. }
  4488. if (currentLength == 0) {
  4489. // Behave as if the read end is always non-blocking
  4490. throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
  4491. }
  4492. var toRead = Math.min(currentLength, length);
  4493.  
  4494. var totalRead = toRead;
  4495. var toRemove = 0;
  4496.  
  4497. for (var i = 0; i < pipe.buckets.length; i++) {
  4498. var currBucket = pipe.buckets[i];
  4499. var bucketSize = currBucket.offset - currBucket.roffset;
  4500.  
  4501. if (toRead <= bucketSize) {
  4502. var tmpSlice = currBucket.buffer.subarray(currBucket.roffset, currBucket.offset);
  4503. if (toRead < bucketSize) {
  4504. tmpSlice = tmpSlice.subarray(0, toRead);
  4505. currBucket.roffset += toRead;
  4506. } else {
  4507. toRemove++;
  4508. }
  4509. data.set(tmpSlice);
  4510. break;
  4511. } else {
  4512. var tmpSlice = currBucket.buffer.subarray(currBucket.roffset, currBucket.offset);
  4513. data.set(tmpSlice);
  4514. data = data.subarray(tmpSlice.byteLength);
  4515. toRead -= tmpSlice.byteLength;
  4516. toRemove++;
  4517. }
  4518. }
  4519.  
  4520. if (toRemove && toRemove == pipe.buckets.length) {
  4521. // Do not generate excessive garbage in use cases such as
  4522. // write several bytes, read everything, write several bytes, read everything...
  4523. toRemove--;
  4524. pipe.buckets[toRemove].offset = 0;
  4525. pipe.buckets[toRemove].roffset = 0;
  4526. }
  4527.  
  4528. pipe.buckets.splice(0, toRemove);
  4529.  
  4530. return totalRead;
  4531. },write:function (stream, buffer, offset, length, position /* ignored */) {
  4532. var pipe = stream.node.pipe;
  4533.  
  4534. assert(buffer instanceof ArrayBuffer || ArrayBuffer.isView(buffer));
  4535. var data = buffer.subarray(offset, offset + length);
  4536.  
  4537. var dataLen = data.byteLength;
  4538. if (dataLen <= 0) {
  4539. return 0;
  4540. }
  4541.  
  4542. var currBucket = null;
  4543.  
  4544. if (pipe.buckets.length == 0) {
  4545. currBucket = {
  4546. buffer: new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),
  4547. offset: 0,
  4548. roffset: 0
  4549. };
  4550. pipe.buckets.push(currBucket);
  4551. } else {
  4552. currBucket = pipe.buckets[pipe.buckets.length - 1];
  4553. }
  4554.  
  4555. assert(currBucket.offset <= PIPEFS.BUCKET_BUFFER_SIZE);
  4556.  
  4557. var freeBytesInCurrBuffer = PIPEFS.BUCKET_BUFFER_SIZE - currBucket.offset;
  4558. if (freeBytesInCurrBuffer >= dataLen) {
  4559. currBucket.buffer.set(data, currBucket.offset);
  4560. currBucket.offset += dataLen;
  4561. return dataLen;
  4562. } else if (freeBytesInCurrBuffer > 0) {
  4563. currBucket.buffer.set(data.subarray(0, freeBytesInCurrBuffer), currBucket.offset);
  4564. currBucket.offset += freeBytesInCurrBuffer;
  4565. data = data.subarray(freeBytesInCurrBuffer, data.byteLength);
  4566. }
  4567.  
  4568. var numBuckets = (data.byteLength / PIPEFS.BUCKET_BUFFER_SIZE) | 0;
  4569. var remElements = data.byteLength % PIPEFS.BUCKET_BUFFER_SIZE;
  4570.  
  4571. for (var i = 0; i < numBuckets; i++) {
  4572. var newBucket = {
  4573. buffer: new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),
  4574. offset: PIPEFS.BUCKET_BUFFER_SIZE,
  4575. roffset: 0
  4576. };
  4577. pipe.buckets.push(newBucket);
  4578. newBucket.buffer.set(data.subarray(0, PIPEFS.BUCKET_BUFFER_SIZE));
  4579. data = data.subarray(PIPEFS.BUCKET_BUFFER_SIZE, data.byteLength);
  4580. }
  4581.  
  4582. if (remElements > 0) {
  4583. var newBucket = {
  4584. buffer: new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),
  4585. offset: data.byteLength,
  4586. roffset: 0
  4587. };
  4588. pipe.buckets.push(newBucket);
  4589. newBucket.buffer.set(data);
  4590. }
  4591.  
  4592. return dataLen;
  4593. },close:function (stream) {
  4594. var pipe = stream.node.pipe;
  4595. pipe.buckets = null;
  4596. }},nextname:function () {
  4597. if (!PIPEFS.nextname.current) {
  4598. PIPEFS.nextname.current = 0;
  4599. }
  4600. return 'pipe[' + (PIPEFS.nextname.current++) + ']';
  4601. }};function ___sys_pipe(fdPtr) {try {
  4602.  
  4603. if (fdPtr == 0) {
  4604. throw new FS.ErrnoError(21);
  4605. }
  4606.  
  4607. var res = PIPEFS.createPipe();
  4608.  
  4609. HEAP32[((fdPtr)>>2)]=res.readable_fd;
  4610. HEAP32[(((fdPtr)+(4))>>2)]=res.writable_fd;
  4611.  
  4612. return 0;
  4613. } catch (e) {
  4614. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  4615. return -e.errno;
  4616. }
  4617. }
  4618.  
  4619. function ___sys_read(fd, buf, count) {try {
  4620.  
  4621. var stream = SYSCALLS.getStreamFromFD(fd);
  4622. return FS.read(stream, HEAP8,buf, count);
  4623. } catch (e) {
  4624. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  4625. return -e.errno;
  4626. }
  4627. }
  4628.  
  4629. function ___sys_readlink(path, buf, bufsize) {try {
  4630.  
  4631. path = SYSCALLS.getStr(path);
  4632. return SYSCALLS.doReadlink(path, buf, bufsize);
  4633. } catch (e) {
  4634. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  4635. return -e.errno;
  4636. }
  4637. }
  4638.  
  4639. function ___sys_rename(old_path, new_path) {try {
  4640.  
  4641. old_path = SYSCALLS.getStr(old_path);
  4642. new_path = SYSCALLS.getStr(new_path);
  4643. FS.rename(old_path, new_path);
  4644. return 0;
  4645. } catch (e) {
  4646. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  4647. return -e.errno;
  4648. }
  4649. }
  4650.  
  4651. function ___sys_rmdir(path) {try {
  4652.  
  4653. path = SYSCALLS.getStr(path);
  4654. FS.rmdir(path);
  4655. return 0;
  4656. } catch (e) {
  4657. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  4658. return -e.errno;
  4659. }
  4660. }
  4661.  
  4662.  
  4663. var SOCKFS={mount:function(mount) {
  4664. // If Module['websocket'] has already been defined (e.g. for configuring
  4665. // the subprotocol/url) use that, if not initialise it to a new object.
  4666. Module['websocket'] = (Module['websocket'] &&
  4667. ('object' === typeof Module['websocket'])) ? Module['websocket'] : {};
  4668.  
  4669. // Add the Event registration mechanism to the exported websocket configuration
  4670. // object so we can register network callbacks from native JavaScript too.
  4671. // For more documentation see system/include/emscripten/emscripten.h
  4672. Module['websocket']._callbacks = {};
  4673. Module['websocket']['on'] = /** @this{Object} */ function(event, callback) {
  4674. if ('function' === typeof callback) {
  4675. this._callbacks[event] = callback;
  4676. }
  4677. return this;
  4678. };
  4679.  
  4680. Module['websocket'].emit = /** @this{Object} */ function(event, param) {
  4681. if ('function' === typeof this._callbacks[event]) {
  4682. this._callbacks[event].call(this, param);
  4683. }
  4684. };
  4685.  
  4686. // If debug is enabled register simple default logging callbacks for each Event.
  4687.  
  4688. return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
  4689. },createSocket:function(family, type, protocol) {
  4690. var streaming = type == 1;
  4691. if (protocol) {
  4692. assert(streaming == (protocol == 6)); // if SOCK_STREAM, must be tcp
  4693. }
  4694.  
  4695. // create our internal socket structure
  4696. var sock = {
  4697. family: family,
  4698. type: type,
  4699. protocol: protocol,
  4700. server: null,
  4701. error: null, // Used in getsockopt for SOL_SOCKET/SO_ERROR test
  4702. peers: {},
  4703. pending: [],
  4704. recv_queue: [],
  4705. sock_ops: SOCKFS.websocket_sock_ops
  4706. };
  4707.  
  4708. // create the filesystem node to store the socket structure
  4709. var name = SOCKFS.nextname();
  4710. var node = FS.createNode(SOCKFS.root, name, 49152, 0);
  4711. node.sock = sock;
  4712.  
  4713. // and the wrapping stream that enables library functions such
  4714. // as read and write to indirectly interact with the socket
  4715. var stream = FS.createStream({
  4716. path: name,
  4717. node: node,
  4718. flags: FS.modeStringToFlags('r+'),
  4719. seekable: false,
  4720. stream_ops: SOCKFS.stream_ops
  4721. });
  4722.  
  4723. // map the new stream to the socket structure (sockets have a 1:1
  4724. // relationship with a stream)
  4725. sock.stream = stream;
  4726.  
  4727. return sock;
  4728. },getSocket:function(fd) {
  4729. var stream = FS.getStream(fd);
  4730. if (!stream || !FS.isSocket(stream.node.mode)) {
  4731. return null;
  4732. }
  4733. return stream.node.sock;
  4734. },stream_ops:{poll:function(stream) {
  4735. var sock = stream.node.sock;
  4736. return sock.sock_ops.poll(sock);
  4737. },ioctl:function(stream, request, varargs) {
  4738. var sock = stream.node.sock;
  4739. return sock.sock_ops.ioctl(sock, request, varargs);
  4740. },read:function(stream, buffer, offset, length, position /* ignored */) {
  4741. var sock = stream.node.sock;
  4742. var msg = sock.sock_ops.recvmsg(sock, length);
  4743. if (!msg) {
  4744. // socket is closed
  4745. return 0;
  4746. }
  4747. buffer.set(msg.buffer, offset);
  4748. return msg.buffer.length;
  4749. },write:function(stream, buffer, offset, length, position /* ignored */) {
  4750. var sock = stream.node.sock;
  4751. return sock.sock_ops.sendmsg(sock, buffer, offset, length);
  4752. },close:function(stream) {
  4753. var sock = stream.node.sock;
  4754. sock.sock_ops.close(sock);
  4755. }},nextname:function() {
  4756. if (!SOCKFS.nextname.current) {
  4757. SOCKFS.nextname.current = 0;
  4758. }
  4759. return 'socket[' + (SOCKFS.nextname.current++) + ']';
  4760. },websocket_sock_ops:{createPeer:function(sock, addr, port) {
  4761. var ws;
  4762.  
  4763. if (typeof addr === 'object') {
  4764. ws = addr;
  4765. addr = null;
  4766. port = null;
  4767. }
  4768.  
  4769. if (ws) {
  4770. // for sockets that've already connected (e.g. we're the server)
  4771. // we can inspect the _socket property for the address
  4772. if (ws._socket) {
  4773. addr = ws._socket.remoteAddress;
  4774. port = ws._socket.remotePort;
  4775. }
  4776. // if we're just now initializing a connection to the remote,
  4777. // inspect the url property
  4778. else {
  4779. var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);
  4780. if (!result) {
  4781. throw new Error('WebSocket URL must be in the format ws(s)://address:port');
  4782. }
  4783. addr = result[1];
  4784. port = parseInt(result[2], 10);
  4785. }
  4786. } else {
  4787. // create the actual websocket object and connect
  4788. try {
  4789. // runtimeConfig gets set to true if WebSocket runtime configuration is available.
  4790. var runtimeConfig = (Module['websocket'] && ('object' === typeof Module['websocket']));
  4791.  
  4792. // The default value is 'ws://' the replace is needed because the compiler replaces '//' comments with '#'
  4793. // comments without checking context, so we'd end up with ws:#, the replace swaps the '#' for '//' again.
  4794. var url = 'ws:#'.replace('#', '//');
  4795.  
  4796. if (runtimeConfig) {
  4797. if ('string' === typeof Module['websocket']['url']) {
  4798. url = Module['websocket']['url']; // Fetch runtime WebSocket URL config.
  4799. }
  4800. }
  4801.  
  4802. if (url === 'ws://' || url === 'wss://') { // Is the supplied URL config just a prefix, if so complete it.
  4803. var parts = addr.split('/');
  4804. url = url + parts[0] + ":" + port + "/" + parts.slice(1).join('/');
  4805. }
  4806.  
  4807. // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set.
  4808. var subProtocols = 'binary'; // The default value is 'binary'
  4809.  
  4810. if (runtimeConfig) {
  4811. if ('string' === typeof Module['websocket']['subprotocol']) {
  4812. subProtocols = Module['websocket']['subprotocol']; // Fetch runtime WebSocket subprotocol config.
  4813. }
  4814. }
  4815.  
  4816. // The default WebSocket options
  4817. var opts = undefined;
  4818.  
  4819. if (subProtocols !== 'null') {
  4820. // The regex trims the string (removes spaces at the beginning and end, then splits the string by
  4821. // <any space>,<any space> into an Array. Whitespace removal is important for Websockify and ws.
  4822. subProtocols = subProtocols.replace(/^ +| +$/g,"").split(/ *, */);
  4823.  
  4824. // The node ws library API for specifying optional subprotocol is slightly different than the browser's.
  4825. opts = ENVIRONMENT_IS_NODE ? {'protocol': subProtocols.toString()} : subProtocols;
  4826. }
  4827.  
  4828. // some webservers (azure) does not support subprotocol header
  4829. if (runtimeConfig && null === Module['websocket']['subprotocol']) {
  4830. subProtocols = 'null';
  4831. opts = undefined;
  4832. }
  4833.  
  4834. // If node we use the ws library.
  4835. var WebSocketConstructor;
  4836. if (ENVIRONMENT_IS_NODE) {
  4837. WebSocketConstructor = /** @type{(typeof WebSocket)} */(require('ws'));
  4838. } else
  4839. {
  4840. WebSocketConstructor = WebSocket;
  4841. }
  4842. ws = new WebSocketConstructor(url, opts);
  4843. ws.binaryType = 'arraybuffer';
  4844. } catch (e) {
  4845. throw new FS.ErrnoError(ERRNO_CODES.EHOSTUNREACH);
  4846. }
  4847. }
  4848.  
  4849.  
  4850. var peer = {
  4851. addr: addr,
  4852. port: port,
  4853. socket: ws,
  4854. dgram_send_queue: []
  4855. };
  4856.  
  4857. SOCKFS.websocket_sock_ops.addPeer(sock, peer);
  4858. SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer);
  4859.  
  4860. // if this is a bound dgram socket, send the port number first to allow
  4861. // us to override the ephemeral port reported to us by remotePort on the
  4862. // remote end.
  4863. if (sock.type === 2 && typeof sock.sport !== 'undefined') {
  4864. peer.dgram_send_queue.push(new Uint8Array([
  4865. 255, 255, 255, 255,
  4866. 'p'.charCodeAt(0), 'o'.charCodeAt(0), 'r'.charCodeAt(0), 't'.charCodeAt(0),
  4867. ((sock.sport & 0xff00) >> 8) , (sock.sport & 0xff)
  4868. ]));
  4869. }
  4870.  
  4871. return peer;
  4872. },getPeer:function(sock, addr, port) {
  4873. return sock.peers[addr + ':' + port];
  4874. },addPeer:function(sock, peer) {
  4875. sock.peers[peer.addr + ':' + peer.port] = peer;
  4876. },removePeer:function(sock, peer) {
  4877. delete sock.peers[peer.addr + ':' + peer.port];
  4878. },handlePeerEvents:function(sock, peer) {
  4879. var first = true;
  4880.  
  4881. var handleOpen = function () {
  4882.  
  4883. Module['websocket'].emit('open', sock.stream.fd);
  4884.  
  4885. try {
  4886. var queued = peer.dgram_send_queue.shift();
  4887. while (queued) {
  4888. peer.socket.send(queued);
  4889. queued = peer.dgram_send_queue.shift();
  4890. }
  4891. } catch (e) {
  4892. // not much we can do here in the way of proper error handling as we've already
  4893. // lied and said this data was sent. shut it down.
  4894. peer.socket.close();
  4895. }
  4896. };
  4897.  
  4898. function handleMessage(data) {
  4899. if (typeof data === 'string') {
  4900. var encoder = new TextEncoder(); // should be utf-8
  4901. data = encoder.encode(data); // make a typed array from the string
  4902. } else {
  4903. assert(data.byteLength !== undefined); // must receive an ArrayBuffer
  4904. if (data.byteLength == 0) {
  4905. // An empty ArrayBuffer will emit a pseudo disconnect event
  4906. // as recv/recvmsg will return zero which indicates that a socket
  4907. // has performed a shutdown although the connection has not been disconnected yet.
  4908. return;
  4909. } else {
  4910. data = new Uint8Array(data); // make a typed array view on the array buffer
  4911. }
  4912. }
  4913.  
  4914.  
  4915. // if this is the port message, override the peer's port with it
  4916. var wasfirst = first;
  4917. first = false;
  4918. if (wasfirst &&
  4919. data.length === 10 &&
  4920. data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 &&
  4921. data[4] === 'p'.charCodeAt(0) && data[5] === 'o'.charCodeAt(0) && data[6] === 'r'.charCodeAt(0) && data[7] === 't'.charCodeAt(0)) {
  4922. // update the peer's port and it's key in the peer map
  4923. var newport = ((data[8] << 8) | data[9]);
  4924. SOCKFS.websocket_sock_ops.removePeer(sock, peer);
  4925. peer.port = newport;
  4926. SOCKFS.websocket_sock_ops.addPeer(sock, peer);
  4927. return;
  4928. }
  4929.  
  4930. sock.recv_queue.push({ addr: peer.addr, port: peer.port, data: data });
  4931. Module['websocket'].emit('message', sock.stream.fd);
  4932. };
  4933.  
  4934. if (ENVIRONMENT_IS_NODE) {
  4935. peer.socket.on('open', handleOpen);
  4936. peer.socket.on('message', function(data, flags) {
  4937. if (!flags.binary) {
  4938. return;
  4939. }
  4940. handleMessage((new Uint8Array(data)).buffer); // copy from node Buffer -> ArrayBuffer
  4941. });
  4942. peer.socket.on('close', function() {
  4943. Module['websocket'].emit('close', sock.stream.fd);
  4944. });
  4945. peer.socket.on('error', function(error) {
  4946. // Although the ws library may pass errors that may be more descriptive than
  4947. // ECONNREFUSED they are not necessarily the expected error code e.g.
  4948. // ENOTFOUND on getaddrinfo seems to be node.js specific, so using ECONNREFUSED
  4949. // is still probably the most useful thing to do.
  4950. sock.error = ERRNO_CODES.ECONNREFUSED; // Used in getsockopt for SOL_SOCKET/SO_ERROR test.
  4951. Module['websocket'].emit('error', [sock.stream.fd, sock.error, 'ECONNREFUSED: Connection refused']);
  4952. // don't throw
  4953. });
  4954. } else {
  4955. peer.socket.onopen = handleOpen;
  4956. peer.socket.onclose = function() {
  4957. Module['websocket'].emit('close', sock.stream.fd);
  4958. };
  4959. peer.socket.onmessage = function peer_socket_onmessage(event) {
  4960. handleMessage(event.data);
  4961. };
  4962. peer.socket.onerror = function(error) {
  4963. // The WebSocket spec only allows a 'simple event' to be thrown on error,
  4964. // so we only really know as much as ECONNREFUSED.
  4965. sock.error = ERRNO_CODES.ECONNREFUSED; // Used in getsockopt for SOL_SOCKET/SO_ERROR test.
  4966. Module['websocket'].emit('error', [sock.stream.fd, sock.error, 'ECONNREFUSED: Connection refused']);
  4967. };
  4968. }
  4969. },poll:function(sock) {
  4970. if (sock.type === 1 && sock.server) {
  4971. // listen sockets should only say they're available for reading
  4972. // if there are pending clients.
  4973. return sock.pending.length ? (64 | 1) : 0;
  4974. }
  4975.  
  4976. var mask = 0;
  4977. var dest = sock.type === 1 ? // we only care about the socket state for connection-based sockets
  4978. SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) :
  4979. null;
  4980.  
  4981. if (sock.recv_queue.length ||
  4982. !dest || // connection-less sockets are always ready to read
  4983. (dest && dest.socket.readyState === dest.socket.CLOSING) ||
  4984. (dest && dest.socket.readyState === dest.socket.CLOSED)) { // let recv return 0 once closed
  4985. mask |= (64 | 1);
  4986. }
  4987.  
  4988. if (!dest || // connection-less sockets are always ready to write
  4989. (dest && dest.socket.readyState === dest.socket.OPEN)) {
  4990. mask |= 4;
  4991. }
  4992.  
  4993. if ((dest && dest.socket.readyState === dest.socket.CLOSING) ||
  4994. (dest && dest.socket.readyState === dest.socket.CLOSED)) {
  4995. mask |= 16;
  4996. }
  4997.  
  4998. return mask;
  4999. },ioctl:function(sock, request, arg) {
  5000. switch (request) {
  5001. case 21531:
  5002. var bytes = 0;
  5003. if (sock.recv_queue.length) {
  5004. bytes = sock.recv_queue[0].data.length;
  5005. }
  5006. HEAP32[((arg)>>2)]=bytes;
  5007. return 0;
  5008. default:
  5009. return ERRNO_CODES.EINVAL;
  5010. }
  5011. },close:function(sock) {
  5012. // if we've spawned a listen server, close it
  5013. if (sock.server) {
  5014. try {
  5015. sock.server.close();
  5016. } catch (e) {
  5017. }
  5018. sock.server = null;
  5019. }
  5020. // close any peer connections
  5021. var peers = Object.keys(sock.peers);
  5022. for (var i = 0; i < peers.length; i++) {
  5023. var peer = sock.peers[peers[i]];
  5024. try {
  5025. peer.socket.close();
  5026. } catch (e) {
  5027. }
  5028. SOCKFS.websocket_sock_ops.removePeer(sock, peer);
  5029. }
  5030. return 0;
  5031. },bind:function(sock, addr, port) {
  5032. if (typeof sock.saddr !== 'undefined' || typeof sock.sport !== 'undefined') {
  5033. throw new FS.ErrnoError(ERRNO_CODES.EINVAL); // already bound
  5034. }
  5035. sock.saddr = addr;
  5036. sock.sport = port;
  5037. // in order to emulate dgram sockets, we need to launch a listen server when
  5038. // binding on a connection-less socket
  5039. // note: this is only required on the server side
  5040. if (sock.type === 2) {
  5041. // close the existing server if it exists
  5042. if (sock.server) {
  5043. sock.server.close();
  5044. sock.server = null;
  5045. }
  5046. // swallow error operation not supported error that occurs when binding in the
  5047. // browser where this isn't supported
  5048. try {
  5049. sock.sock_ops.listen(sock, 0);
  5050. } catch (e) {
  5051. if (!(e instanceof FS.ErrnoError)) throw e;
  5052. if (e.errno !== ERRNO_CODES.EOPNOTSUPP) throw e;
  5053. }
  5054. }
  5055. },connect:function(sock, addr, port) {
  5056. if (sock.server) {
  5057. throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
  5058. }
  5059.  
  5060. // TODO autobind
  5061. // if (!sock.addr && sock.type == 2) {
  5062. // }
  5063.  
  5064. // early out if we're already connected / in the middle of connecting
  5065. if (typeof sock.daddr !== 'undefined' && typeof sock.dport !== 'undefined') {
  5066. var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
  5067. if (dest) {
  5068. if (dest.socket.readyState === dest.socket.CONNECTING) {
  5069. throw new FS.ErrnoError(ERRNO_CODES.EALREADY);
  5070. } else {
  5071. throw new FS.ErrnoError(ERRNO_CODES.EISCONN);
  5072. }
  5073. }
  5074. }
  5075.  
  5076. // add the socket to our peer list and set our
  5077. // destination address / port to match
  5078. var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
  5079. sock.daddr = peer.addr;
  5080. sock.dport = peer.port;
  5081.  
  5082. // always "fail" in non-blocking mode
  5083. throw new FS.ErrnoError(ERRNO_CODES.EINPROGRESS);
  5084. },listen:function(sock, backlog) {
  5085. if (!ENVIRONMENT_IS_NODE) {
  5086. throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
  5087. }
  5088. if (sock.server) {
  5089. throw new FS.ErrnoError(ERRNO_CODES.EINVAL); // already listening
  5090. }
  5091. var WebSocketServer = require('ws').Server;
  5092. var host = sock.saddr;
  5093. sock.server = new WebSocketServer({
  5094. host: host,
  5095. port: sock.sport
  5096. // TODO support backlog
  5097. });
  5098. Module['websocket'].emit('listen', sock.stream.fd); // Send Event with listen fd.
  5099.  
  5100. sock.server.on('connection', function(ws) {
  5101. if (sock.type === 1) {
  5102. var newsock = SOCKFS.createSocket(sock.family, sock.type, sock.protocol);
  5103.  
  5104. // create a peer on the new socket
  5105. var peer = SOCKFS.websocket_sock_ops.createPeer(newsock, ws);
  5106. newsock.daddr = peer.addr;
  5107. newsock.dport = peer.port;
  5108.  
  5109. // push to queue for accept to pick up
  5110. sock.pending.push(newsock);
  5111. Module['websocket'].emit('connection', newsock.stream.fd);
  5112. } else {
  5113. // create a peer on the listen socket so calling sendto
  5114. // with the listen socket and an address will resolve
  5115. // to the correct client
  5116. SOCKFS.websocket_sock_ops.createPeer(sock, ws);
  5117. Module['websocket'].emit('connection', sock.stream.fd);
  5118. }
  5119. });
  5120. sock.server.on('closed', function() {
  5121. Module['websocket'].emit('close', sock.stream.fd);
  5122. sock.server = null;
  5123. });
  5124. sock.server.on('error', function(error) {
  5125. // Although the ws library may pass errors that may be more descriptive than
  5126. // ECONNREFUSED they are not necessarily the expected error code e.g.
  5127. // ENOTFOUND on getaddrinfo seems to be node.js specific, so using EHOSTUNREACH
  5128. // is still probably the most useful thing to do. This error shouldn't
  5129. // occur in a well written app as errors should get trapped in the compiled
  5130. // app's own getaddrinfo call.
  5131. sock.error = ERRNO_CODES.EHOSTUNREACH; // Used in getsockopt for SOL_SOCKET/SO_ERROR test.
  5132. Module['websocket'].emit('error', [sock.stream.fd, sock.error, 'EHOSTUNREACH: Host is unreachable']);
  5133. // don't throw
  5134. });
  5135. },accept:function(listensock) {
  5136. if (!listensock.server) {
  5137. throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
  5138. }
  5139. var newsock = listensock.pending.shift();
  5140. newsock.stream.flags = listensock.stream.flags;
  5141. return newsock;
  5142. },getname:function(sock, peer) {
  5143. var addr, port;
  5144. if (peer) {
  5145. if (sock.daddr === undefined || sock.dport === undefined) {
  5146. throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
  5147. }
  5148. addr = sock.daddr;
  5149. port = sock.dport;
  5150. } else {
  5151. // TODO saddr and sport will be set for bind()'d UDP sockets, but what
  5152. // should we be returning for TCP sockets that've been connect()'d?
  5153. addr = sock.saddr || 0;
  5154. port = sock.sport || 0;
  5155. }
  5156. return { addr: addr, port: port };
  5157. },sendmsg:function(sock, buffer, offset, length, addr, port) {
  5158. if (sock.type === 2) {
  5159. // connection-less sockets will honor the message address,
  5160. // and otherwise fall back to the bound destination address
  5161. if (addr === undefined || port === undefined) {
  5162. addr = sock.daddr;
  5163. port = sock.dport;
  5164. }
  5165. // if there was no address to fall back to, error out
  5166. if (addr === undefined || port === undefined) {
  5167. throw new FS.ErrnoError(ERRNO_CODES.EDESTADDRREQ);
  5168. }
  5169. } else {
  5170. // connection-based sockets will only use the bound
  5171. addr = sock.daddr;
  5172. port = sock.dport;
  5173. }
  5174.  
  5175. // find the peer for the destination address
  5176. var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port);
  5177.  
  5178. // early out if not connected with a connection-based socket
  5179. if (sock.type === 1) {
  5180. if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
  5181. throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
  5182. } else if (dest.socket.readyState === dest.socket.CONNECTING) {
  5183. throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
  5184. }
  5185. }
  5186.  
  5187. // create a copy of the incoming data to send, as the WebSocket API
  5188. // doesn't work entirely with an ArrayBufferView, it'll just send
  5189. // the entire underlying buffer
  5190. if (ArrayBuffer.isView(buffer)) {
  5191. offset += buffer.byteOffset;
  5192. buffer = buffer.buffer;
  5193. }
  5194.  
  5195. var data;
  5196. data = buffer.slice(offset, offset + length);
  5197.  
  5198. // if we're emulating a connection-less dgram socket and don't have
  5199. // a cached connection, queue the buffer to send upon connect and
  5200. // lie, saying the data was sent now.
  5201. if (sock.type === 2) {
  5202. if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
  5203. // if we're not connected, open a new connection
  5204. if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
  5205. dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
  5206. }
  5207. dest.dgram_send_queue.push(data);
  5208. return length;
  5209. }
  5210. }
  5211.  
  5212. try {
  5213. // send the actual data
  5214. dest.socket.send(data);
  5215. return length;
  5216. } catch (e) {
  5217. throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
  5218. }
  5219. },recvmsg:function(sock, length) {
  5220. // http://pubs.opengroup.org/onlinepubs/7908799/xns/recvmsg.html
  5221. if (sock.type === 1 && sock.server) {
  5222. // tcp servers should not be recv()'ing on the listen socket
  5223. throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
  5224. }
  5225.  
  5226. var queued = sock.recv_queue.shift();
  5227. if (!queued) {
  5228. if (sock.type === 1) {
  5229. var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
  5230.  
  5231. if (!dest) {
  5232. // if we have a destination address but are not connected, error out
  5233. throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
  5234. }
  5235. else if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
  5236. // return null if the socket has closed
  5237. return null;
  5238. }
  5239. else {
  5240. // else, our socket is in a valid state but truly has nothing available
  5241. throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
  5242. }
  5243. } else {
  5244. throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
  5245. }
  5246. }
  5247.  
  5248. // queued.data will be an ArrayBuffer if it's unadulterated, but if it's
  5249. // requeued TCP data it'll be an ArrayBufferView
  5250. var queuedLength = queued.data.byteLength || queued.data.length;
  5251. var queuedOffset = queued.data.byteOffset || 0;
  5252. var queuedBuffer = queued.data.buffer || queued.data;
  5253. var bytesRead = Math.min(length, queuedLength);
  5254. var res = {
  5255. buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead),
  5256. addr: queued.addr,
  5257. port: queued.port
  5258. };
  5259.  
  5260.  
  5261. // push back any unread data for TCP connections
  5262. if (sock.type === 1 && bytesRead < queuedLength) {
  5263. var bytesRemaining = queuedLength - bytesRead;
  5264. queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining);
  5265. sock.recv_queue.unshift(queued);
  5266. }
  5267.  
  5268. return res;
  5269. }}};
  5270.  
  5271.  
  5272. function __inet_pton4_raw(str) {
  5273. var b = str.split('.');
  5274. for (var i = 0; i < 4; i++) {
  5275. var tmp = Number(b[i]);
  5276. if (isNaN(tmp)) return null;
  5277. b[i] = tmp;
  5278. }
  5279. return (b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24)) >>> 0;
  5280. }
  5281.  
  5282.  
  5283. /** @suppress {checkTypes} */
  5284. function jstoi_q(str) {
  5285. return parseInt(str);
  5286. }function __inet_pton6_raw(str) {
  5287. var words;
  5288. var w, offset, z, i;
  5289. /* http://home.deds.nl/~aeron/regex/ */
  5290. var valid6regx = /^((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\3)::|:\b|$))|(?!\2\3)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i
  5291. var parts = [];
  5292. if (!valid6regx.test(str)) {
  5293. return null;
  5294. }
  5295. if (str === "::") {
  5296. return [0, 0, 0, 0, 0, 0, 0, 0];
  5297. }
  5298. // Z placeholder to keep track of zeros when splitting the string on ":"
  5299. if (str.indexOf("::") === 0) {
  5300. str = str.replace("::", "Z:"); // leading zeros case
  5301. } else {
  5302. str = str.replace("::", ":Z:");
  5303. }
  5304.  
  5305. if (str.indexOf(".") > 0) {
  5306. // parse IPv4 embedded stress
  5307. str = str.replace(new RegExp('[.]', 'g'), ":");
  5308. words = str.split(":");
  5309. words[words.length-4] = jstoi_q(words[words.length-4]) + jstoi_q(words[words.length-3])*256;
  5310. words[words.length-3] = jstoi_q(words[words.length-2]) + jstoi_q(words[words.length-1])*256;
  5311. words = words.slice(0, words.length-2);
  5312. } else {
  5313. words = str.split(":");
  5314. }
  5315.  
  5316. offset = 0; z = 0;
  5317. for (w=0; w < words.length; w++) {
  5318. if (typeof words[w] === 'string') {
  5319. if (words[w] === 'Z') {
  5320. // compressed zeros - write appropriate number of zero words
  5321. for (z = 0; z < (8 - words.length+1); z++) {
  5322. parts[w+z] = 0;
  5323. }
  5324. offset = z-1;
  5325. } else {
  5326. // parse hex to field to 16-bit value and write it in network byte-order
  5327. parts[w+offset] = _htons(parseInt(words[w],16));
  5328. }
  5329. } else {
  5330. // parsed IPv4 words
  5331. parts[w+offset] = words[w];
  5332. }
  5333. }
  5334. return [
  5335. (parts[1] << 16) | parts[0],
  5336. (parts[3] << 16) | parts[2],
  5337. (parts[5] << 16) | parts[4],
  5338. (parts[7] << 16) | parts[6]
  5339. ];
  5340. }var DNS={address_map:{id:1,addrs:{},names:{}},lookup_name:function (name) {
  5341. // If the name is already a valid ipv4 / ipv6 address, don't generate a fake one.
  5342. var res = __inet_pton4_raw(name);
  5343. if (res !== null) {
  5344. return name;
  5345. }
  5346. res = __inet_pton6_raw(name);
  5347. if (res !== null) {
  5348. return name;
  5349. }
  5350.  
  5351. // See if this name is already mapped.
  5352. var addr;
  5353.  
  5354. if (DNS.address_map.addrs[name]) {
  5355. addr = DNS.address_map.addrs[name];
  5356. } else {
  5357. var id = DNS.address_map.id++;
  5358. assert(id < 65535, 'exceeded max address mappings of 65535');
  5359.  
  5360. addr = '172.29.' + (id & 0xff) + '.' + (id & 0xff00);
  5361.  
  5362. DNS.address_map.names[addr] = name;
  5363. DNS.address_map.addrs[name] = addr;
  5364. }
  5365.  
  5366. return addr;
  5367. },lookup_addr:function (addr) {
  5368. if (DNS.address_map.names[addr]) {
  5369. return DNS.address_map.names[addr];
  5370. }
  5371.  
  5372. return null;
  5373. }};
  5374.  
  5375.  
  5376. var Sockets={BUFFER_SIZE:10240,MAX_BUFFER_SIZE:10485760,nextFd:1,fds:{},nextport:1,maxport:65535,peer:null,connections:{},portmap:{},localAddr:4261412874,addrPool:[33554442,50331658,67108874,83886090,100663306,117440522,134217738,150994954,167772170,184549386,201326602,218103818,234881034]};
  5377.  
  5378. function __inet_ntop4_raw(addr) {
  5379. return (addr & 0xff) + '.' + ((addr >> 8) & 0xff) + '.' + ((addr >> 16) & 0xff) + '.' + ((addr >> 24) & 0xff)
  5380. }
  5381.  
  5382. function __inet_ntop6_raw(ints) {
  5383. // ref: http://www.ietf.org/rfc/rfc2373.txt - section 2.5.4
  5384. // Format for IPv4 compatible and mapped 128-bit IPv6 Addresses
  5385. // 128-bits are split into eight 16-bit words
  5386. // stored in network byte order (big-endian)
  5387. // | 80 bits | 16 | 32 bits |
  5388. // +-----------------------------------------------------------------+
  5389. // | 10 bytes | 2 | 4 bytes |
  5390. // +--------------------------------------+--------------------------+
  5391. // + 5 words | 1 | 2 words |
  5392. // +--------------------------------------+--------------------------+
  5393. // |0000..............................0000|0000| IPv4 ADDRESS | (compatible)
  5394. // +--------------------------------------+----+---------------------+
  5395. // |0000..............................0000|FFFF| IPv4 ADDRESS | (mapped)
  5396. // +--------------------------------------+----+---------------------+
  5397. var str = "";
  5398. var word = 0;
  5399. var longest = 0;
  5400. var lastzero = 0;
  5401. var zstart = 0;
  5402. var len = 0;
  5403. var i = 0;
  5404. var parts = [
  5405. ints[0] & 0xffff,
  5406. (ints[0] >> 16),
  5407. ints[1] & 0xffff,
  5408. (ints[1] >> 16),
  5409. ints[2] & 0xffff,
  5410. (ints[2] >> 16),
  5411. ints[3] & 0xffff,
  5412. (ints[3] >> 16)
  5413. ];
  5414.  
  5415. // Handle IPv4-compatible, IPv4-mapped, loopback and any/unspecified addresses
  5416.  
  5417. var hasipv4 = true;
  5418. var v4part = "";
  5419. // check if the 10 high-order bytes are all zeros (first 5 words)
  5420. for (i = 0; i < 5; i++) {
  5421. if (parts[i] !== 0) { hasipv4 = false; break; }
  5422. }
  5423.  
  5424. if (hasipv4) {
  5425. // low-order 32-bits store an IPv4 address (bytes 13 to 16) (last 2 words)
  5426. v4part = __inet_ntop4_raw(parts[6] | (parts[7] << 16));
  5427. // IPv4-mapped IPv6 address if 16-bit value (bytes 11 and 12) == 0xFFFF (6th word)
  5428. if (parts[5] === -1) {
  5429. str = "::ffff:";
  5430. str += v4part;
  5431. return str;
  5432. }
  5433. // IPv4-compatible IPv6 address if 16-bit value (bytes 11 and 12) == 0x0000 (6th word)
  5434. if (parts[5] === 0) {
  5435. str = "::";
  5436. //special case IPv6 addresses
  5437. if(v4part === "0.0.0.0") v4part = ""; // any/unspecified address
  5438. if(v4part === "0.0.0.1") v4part = "1";// loopback address
  5439. str += v4part;
  5440. return str;
  5441. }
  5442. }
  5443.  
  5444. // Handle all other IPv6 addresses
  5445.  
  5446. // first run to find the longest contiguous zero words
  5447. for (word = 0; word < 8; word++) {
  5448. if (parts[word] === 0) {
  5449. if (word - lastzero > 1) {
  5450. len = 0;
  5451. }
  5452. lastzero = word;
  5453. len++;
  5454. }
  5455. if (len > longest) {
  5456. longest = len;
  5457. zstart = word - longest + 1;
  5458. }
  5459. }
  5460.  
  5461. for (word = 0; word < 8; word++) {
  5462. if (longest > 1) {
  5463. // compress contiguous zeros - to produce "::"
  5464. if (parts[word] === 0 && word >= zstart && word < (zstart + longest) ) {
  5465. if (word === zstart) {
  5466. str += ":";
  5467. if (zstart === 0) str += ":"; //leading zeros case
  5468. }
  5469. continue;
  5470. }
  5471. }
  5472. // converts 16-bit words from big-endian to little-endian before converting to hex string
  5473. str += Number(_ntohs(parts[word] & 0xffff)).toString(16);
  5474. str += word < 7 ? ":" : "";
  5475. }
  5476. return str;
  5477. }function __read_sockaddr(sa, salen) {
  5478. // family / port offsets are common to both sockaddr_in and sockaddr_in6
  5479. var family = HEAP16[((sa)>>1)];
  5480. var port = _ntohs(HEAPU16[(((sa)+(2))>>1)]);
  5481. var addr;
  5482.  
  5483. switch (family) {
  5484. case 2:
  5485. if (salen !== 16) {
  5486. return { errno: 28 };
  5487. }
  5488. addr = HEAP32[(((sa)+(4))>>2)];
  5489. addr = __inet_ntop4_raw(addr);
  5490. break;
  5491. case 10:
  5492. if (salen !== 28) {
  5493. return { errno: 28 };
  5494. }
  5495. addr = [
  5496. HEAP32[(((sa)+(8))>>2)],
  5497. HEAP32[(((sa)+(12))>>2)],
  5498. HEAP32[(((sa)+(16))>>2)],
  5499. HEAP32[(((sa)+(20))>>2)]
  5500. ];
  5501. addr = __inet_ntop6_raw(addr);
  5502. break;
  5503. default:
  5504. return { errno: 5 };
  5505. }
  5506.  
  5507. return { family: family, addr: addr, port: port };
  5508. }
  5509.  
  5510. function __write_sockaddr(sa, family, addr, port) {
  5511. switch (family) {
  5512. case 2:
  5513. addr = __inet_pton4_raw(addr);
  5514. HEAP16[((sa)>>1)]=family;
  5515. HEAP32[(((sa)+(4))>>2)]=addr;
  5516. HEAP16[(((sa)+(2))>>1)]=_htons(port);
  5517. break;
  5518. case 10:
  5519. addr = __inet_pton6_raw(addr);
  5520. HEAP32[((sa)>>2)]=family;
  5521. HEAP32[(((sa)+(8))>>2)]=addr[0];
  5522. HEAP32[(((sa)+(12))>>2)]=addr[1];
  5523. HEAP32[(((sa)+(16))>>2)]=addr[2];
  5524. HEAP32[(((sa)+(20))>>2)]=addr[3];
  5525. HEAP16[(((sa)+(2))>>1)]=_htons(port);
  5526. HEAP32[(((sa)+(4))>>2)]=0;
  5527. HEAP32[(((sa)+(24))>>2)]=0;
  5528. break;
  5529. default:
  5530. return { errno: 5 };
  5531. }
  5532. // kind of lame, but let's match _read_sockaddr's interface
  5533. return {};
  5534. }function ___sys_socketcall(call, socketvararg) {try {
  5535.  
  5536. // socketcalls pass the rest of the arguments in a struct
  5537. SYSCALLS.varargs = socketvararg;
  5538.  
  5539. var getSocketFromFD = function() {
  5540. var socket = SOCKFS.getSocket(SYSCALLS.get());
  5541. if (!socket) throw new FS.ErrnoError(8);
  5542. return socket;
  5543. };
  5544. /** @param {boolean=} allowNull */
  5545. var getSocketAddress = function(allowNull) {
  5546. var addrp = SYSCALLS.get(), addrlen = SYSCALLS.get();
  5547. if (allowNull && addrp === 0) return null;
  5548. var info = __read_sockaddr(addrp, addrlen);
  5549. if (info.errno) throw new FS.ErrnoError(info.errno);
  5550. info.addr = DNS.lookup_addr(info.addr) || info.addr;
  5551. return info;
  5552. };
  5553.  
  5554. switch (call) {
  5555. case 1: { // socket
  5556. var domain = SYSCALLS.get(), type = SYSCALLS.get(), protocol = SYSCALLS.get();
  5557. var sock = SOCKFS.createSocket(domain, type, protocol);
  5558. return sock.stream.fd;
  5559. }
  5560. case 2: { // bind
  5561. var sock = getSocketFromFD(), info = getSocketAddress();
  5562. sock.sock_ops.bind(sock, info.addr, info.port);
  5563. return 0;
  5564. }
  5565. case 3: { // connect
  5566. var sock = getSocketFromFD(), info = getSocketAddress();
  5567. sock.sock_ops.connect(sock, info.addr, info.port);
  5568. return 0;
  5569. }
  5570. case 4: { // listen
  5571. var sock = getSocketFromFD(), backlog = SYSCALLS.get();
  5572. sock.sock_ops.listen(sock, backlog);
  5573. return 0;
  5574. }
  5575. case 5: { // accept
  5576. var sock = getSocketFromFD(), addr = SYSCALLS.get(), addrlen = SYSCALLS.get();
  5577. var newsock = sock.sock_ops.accept(sock);
  5578. if (addr) {
  5579. var res = __write_sockaddr(addr, newsock.family, DNS.lookup_name(newsock.daddr), newsock.dport);
  5580. }
  5581. return newsock.stream.fd;
  5582. }
  5583. case 6: { // getsockname
  5584. var sock = getSocketFromFD(), addr = SYSCALLS.get(), addrlen = SYSCALLS.get();
  5585. // TODO: sock.saddr should never be undefined, see TODO in websocket_sock_ops.getname
  5586. var res = __write_sockaddr(addr, sock.family, DNS.lookup_name(sock.saddr || '0.0.0.0'), sock.sport);
  5587. return 0;
  5588. }
  5589. case 7: { // getpeername
  5590. var sock = getSocketFromFD(), addr = SYSCALLS.get(), addrlen = SYSCALLS.get();
  5591. if (!sock.daddr) {
  5592. return -53; // The socket is not connected.
  5593. }
  5594. var res = __write_sockaddr(addr, sock.family, DNS.lookup_name(sock.daddr), sock.dport);
  5595. return 0;
  5596. }
  5597. case 11: { // sendto
  5598. var sock = getSocketFromFD(), message = SYSCALLS.get(), length = SYSCALLS.get(), flags = SYSCALLS.get(), dest = getSocketAddress(true);
  5599. if (!dest) {
  5600. // send, no address provided
  5601. return FS.write(sock.stream, HEAP8,message, length);
  5602. } else {
  5603. // sendto an address
  5604. return sock.sock_ops.sendmsg(sock, HEAP8,message, length, dest.addr, dest.port);
  5605. }
  5606. }
  5607. case 12: { // recvfrom
  5608. var sock = getSocketFromFD(), buf = SYSCALLS.get(), len = SYSCALLS.get(), flags = SYSCALLS.get(), addr = SYSCALLS.get(), addrlen = SYSCALLS.get();
  5609. var msg = sock.sock_ops.recvmsg(sock, len);
  5610. if (!msg) return 0; // socket is closed
  5611. if (addr) {
  5612. var res = __write_sockaddr(addr, sock.family, DNS.lookup_name(msg.addr), msg.port);
  5613. }
  5614. HEAPU8.set(msg.buffer, buf);
  5615. return msg.buffer.byteLength;
  5616. }
  5617. case 14: { // setsockopt
  5618. return -50; // The option is unknown at the level indicated.
  5619. }
  5620. case 15: { // getsockopt
  5621. var sock = getSocketFromFD(), level = SYSCALLS.get(), optname = SYSCALLS.get(), optval = SYSCALLS.get(), optlen = SYSCALLS.get();
  5622. // Minimal getsockopt aimed at resolving https://github.com/emscripten-core/emscripten/issues/2211
  5623. // so only supports SOL_SOCKET with SO_ERROR.
  5624. if (level === 1) {
  5625. if (optname === 4) {
  5626. HEAP32[((optval)>>2)]=sock.error;
  5627. HEAP32[((optlen)>>2)]=4;
  5628. sock.error = null; // Clear the error (The SO_ERROR option obtains and then clears this field).
  5629. return 0;
  5630. }
  5631. }
  5632. return -50; // The option is unknown at the level indicated.
  5633. }
  5634. case 16: { // sendmsg
  5635. var sock = getSocketFromFD(), message = SYSCALLS.get(), flags = SYSCALLS.get();
  5636. var iov = HEAP32[(((message)+(8))>>2)];
  5637. var num = HEAP32[(((message)+(12))>>2)];
  5638. // read the address and port to send to
  5639. var addr, port;
  5640. var name = HEAP32[((message)>>2)];
  5641. var namelen = HEAP32[(((message)+(4))>>2)];
  5642. if (name) {
  5643. var info = __read_sockaddr(name, namelen);
  5644. if (info.errno) return -info.errno;
  5645. port = info.port;
  5646. addr = DNS.lookup_addr(info.addr) || info.addr;
  5647. }
  5648. // concatenate scatter-gather arrays into one message buffer
  5649. var total = 0;
  5650. for (var i = 0; i < num; i++) {
  5651. total += HEAP32[(((iov)+((8 * i) + 4))>>2)];
  5652. }
  5653. var view = new Uint8Array(total);
  5654. var offset = 0;
  5655. for (var i = 0; i < num; i++) {
  5656. var iovbase = HEAP32[(((iov)+((8 * i) + 0))>>2)];
  5657. var iovlen = HEAP32[(((iov)+((8 * i) + 4))>>2)];
  5658. for (var j = 0; j < iovlen; j++) {
  5659. view[offset++] = HEAP8[(((iovbase)+(j))>>0)];
  5660. }
  5661. }
  5662. // write the buffer
  5663. return sock.sock_ops.sendmsg(sock, view, 0, total, addr, port);
  5664. }
  5665. case 17: { // recvmsg
  5666. var sock = getSocketFromFD(), message = SYSCALLS.get(), flags = SYSCALLS.get();
  5667. var iov = HEAP32[(((message)+(8))>>2)];
  5668. var num = HEAP32[(((message)+(12))>>2)];
  5669. // get the total amount of data we can read across all arrays
  5670. var total = 0;
  5671. for (var i = 0; i < num; i++) {
  5672. total += HEAP32[(((iov)+((8 * i) + 4))>>2)];
  5673. }
  5674. // try to read total data
  5675. var msg = sock.sock_ops.recvmsg(sock, total);
  5676. if (!msg) return 0; // socket is closed
  5677.  
  5678. // TODO honor flags:
  5679. // MSG_OOB
  5680. // Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific.
  5681. // MSG_PEEK
  5682. // Peeks at the incoming message.
  5683. // MSG_WAITALL
  5684. // Requests that the function block until the full amount of data requested can be returned. The function may return a smaller amount of data if a signal is caught, if the connection is terminated, if MSG_PEEK was specified, or if an error is pending for the socket.
  5685.  
  5686. // write the source address out
  5687. var name = HEAP32[((message)>>2)];
  5688. if (name) {
  5689. var res = __write_sockaddr(name, sock.family, DNS.lookup_name(msg.addr), msg.port);
  5690. }
  5691. // write the buffer out to the scatter-gather arrays
  5692. var bytesRead = 0;
  5693. var bytesRemaining = msg.buffer.byteLength;
  5694. for (var i = 0; bytesRemaining > 0 && i < num; i++) {
  5695. var iovbase = HEAP32[(((iov)+((8 * i) + 0))>>2)];
  5696. var iovlen = HEAP32[(((iov)+((8 * i) + 4))>>2)];
  5697. if (!iovlen) {
  5698. continue;
  5699. }
  5700. var length = Math.min(iovlen, bytesRemaining);
  5701. var buf = msg.buffer.subarray(bytesRead, bytesRead + length);
  5702. HEAPU8.set(buf, iovbase + bytesRead);
  5703. bytesRead += length;
  5704. bytesRemaining -= length;
  5705. }
  5706.  
  5707. // TODO set msghdr.msg_flags
  5708. // MSG_EOR
  5709. // End of record was received (if supported by the protocol).
  5710. // MSG_OOB
  5711. // Out-of-band data was received.
  5712. // MSG_TRUNC
  5713. // Normal data was truncated.
  5714. // MSG_CTRUNC
  5715.  
  5716. return bytesRead;
  5717. }
  5718. default: {
  5719. return -52; // unsupported feature
  5720. }
  5721. }
  5722. } catch (e) {
  5723. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  5724. return -e.errno;
  5725. }
  5726. }
  5727.  
  5728. function ___sys_stat64(path, buf) {try {
  5729.  
  5730. path = SYSCALLS.getStr(path);
  5731. return SYSCALLS.doStat(FS.stat, path, buf);
  5732. } catch (e) {
  5733. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  5734. return -e.errno;
  5735. }
  5736. }
  5737.  
  5738. function ___sys_unlink(path) {try {
  5739.  
  5740. path = SYSCALLS.getStr(path);
  5741. FS.unlink(path);
  5742. return 0;
  5743. } catch (e) {
  5744. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  5745. return -e.errno;
  5746. }
  5747. }
  5748.  
  5749. function ___sys_wait4(pid, wstart, options, rusage) {try {
  5750.  
  5751. abort('cannot wait on child processes');
  5752. } catch (e) {
  5753. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  5754. return -e.errno;
  5755. }
  5756. }
  5757.  
  5758. function ___wait() {}
  5759.  
  5760.  
  5761. function _exit(status) {
  5762. // void _exit(int status);
  5763. // http://pubs.opengroup.org/onlinepubs/000095399/functions/exit.html
  5764. exit(status);
  5765. }function __exit(a0
  5766. ) {
  5767. return _exit(a0);
  5768. }
  5769.  
  5770. function _abort() {
  5771. abort();
  5772. }
  5773.  
  5774. function _emscripten_get_sbrk_ptr() {
  5775. return 977632;
  5776. }
  5777.  
  5778.  
  5779.  
  5780.  
  5781. var setjmpId=0;function _saveSetjmp(env, label, table, size) {
  5782. // Not particularly fast: slow table lookup of setjmpId to label. But setjmp
  5783. // prevents relooping anyhow, so slowness is to be expected. And typical case
  5784. // is 1 setjmp per invocation, or less.
  5785. env = env|0;
  5786. label = label|0;
  5787. table = table|0;
  5788. size = size|0;
  5789. var i = 0;
  5790. setjmpId = (setjmpId+1)|0;
  5791. HEAP32[((env)>>2)]=setjmpId;
  5792. while ((i|0) < (size|0)) {
  5793. if (((HEAP32[(((table)+((i<<3)))>>2)])|0) == 0) {
  5794. HEAP32[(((table)+((i<<3)))>>2)]=setjmpId;
  5795. HEAP32[(((table)+((i<<3)+4))>>2)]=label;
  5796. // prepare next slot
  5797. HEAP32[(((table)+((i<<3)+8))>>2)]=0;
  5798. setTempRet0((size) | 0);
  5799. return table | 0;
  5800. }
  5801. i = i+1|0;
  5802. }
  5803. // grow the table
  5804. size = (size*2)|0;
  5805. table = _realloc(table|0, 8*(size+1|0)|0) | 0;
  5806. table = _saveSetjmp(env|0, label|0, table|0, size|0) | 0;
  5807. setTempRet0((size) | 0);
  5808. return table | 0;
  5809. }
  5810.  
  5811. function _testSetjmp(id, table, size) {
  5812. id = id|0;
  5813. table = table|0;
  5814. size = size|0;
  5815. var i = 0, curr = 0;
  5816. while ((i|0) < (size|0)) {
  5817. curr = ((HEAP32[(((table)+((i<<3)))>>2)])|0);
  5818. if ((curr|0) == 0) break;
  5819. if ((curr|0) == (id|0)) {
  5820. return ((HEAP32[(((table)+((i<<3)+4))>>2)])|0);
  5821. }
  5822. i = i+1|0;
  5823. }
  5824. return 0;
  5825. }function _longjmp(env, value) {
  5826. _setThrew(env, value || 1);
  5827. throw 'longjmp';
  5828. }function _emscripten_longjmp(env, value) {
  5829. _longjmp(env, value);
  5830. }
  5831.  
  5832. function _emscripten_memcpy_big(dest, src, num) {
  5833. HEAPU8.copyWithin(dest, src, src + num);
  5834. }
  5835.  
  5836.  
  5837. function _emscripten_get_heap_size() {
  5838. return HEAPU8.length;
  5839. }
  5840.  
  5841. function abortOnCannotGrowMemory(requestedSize) {
  5842. abort('OOM');
  5843. }function _emscripten_resize_heap(requestedSize) {
  5844. requestedSize = requestedSize >>> 0;
  5845. abortOnCannotGrowMemory(requestedSize);
  5846. }
  5847.  
  5848.  
  5849.  
  5850. var ENV={};
  5851.  
  5852. function __getExecutableName() {
  5853. return thisProgram || './this.program';
  5854. }function getEnvStrings() {
  5855. if (!getEnvStrings.strings) {
  5856. // Default values.
  5857. var env = {
  5858. 'USER': 'web_user',
  5859. 'LOGNAME': 'web_user',
  5860. 'PATH': '/',
  5861. 'PWD': '/',
  5862. 'HOME': '/home/web_user',
  5863. // Browser language detection #8751
  5864. 'LANG': ((typeof navigator === 'object' && navigator.languages && navigator.languages[0]) || 'C').replace('-', '_') + '.UTF-8',
  5865. '_': __getExecutableName()
  5866. };
  5867. // Apply the user-provided values, if any.
  5868. for (var x in ENV) {
  5869. env[x] = ENV[x];
  5870. }
  5871. var strings = [];
  5872. for (var x in env) {
  5873. strings.push(x + '=' + env[x]);
  5874. }
  5875. getEnvStrings.strings = strings;
  5876. }
  5877. return getEnvStrings.strings;
  5878. }function _environ_get(__environ, environ_buf) {
  5879. var bufSize = 0;
  5880. getEnvStrings().forEach(function(string, i) {
  5881. var ptr = environ_buf + bufSize;
  5882. HEAP32[(((__environ)+(i * 4))>>2)]=ptr;
  5883. writeAsciiToMemory(string, ptr);
  5884. bufSize += string.length + 1;
  5885. });
  5886. return 0;
  5887. }
  5888.  
  5889. function _environ_sizes_get(penviron_count, penviron_buf_size) {
  5890. var strings = getEnvStrings();
  5891. HEAP32[((penviron_count)>>2)]=strings.length;
  5892. var bufSize = 0;
  5893. strings.forEach(function(string) {
  5894. bufSize += string.length + 1;
  5895. });
  5896. HEAP32[((penviron_buf_size)>>2)]=bufSize;
  5897. return 0;
  5898. }
  5899.  
  5900.  
  5901. function _execl(path, arg0, varArgs) {
  5902. // int execl(const char *path, const char *arg0, ... /*, (char *)0 */);
  5903. // http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html
  5904. // We don't support executing external code.
  5905. setErrNo(45);
  5906. return -1;
  5907. }function _execvp(a0,a1,a2
  5908. ) {
  5909. return _execl(a0,a1,a2);
  5910. }
  5911.  
  5912.  
  5913. function _fd_close(fd) {try {
  5914.  
  5915. var stream = SYSCALLS.getStreamFromFD(fd);
  5916. FS.close(stream);
  5917. return 0;
  5918. } catch (e) {
  5919. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  5920. return e.errno;
  5921. }
  5922. }
  5923.  
  5924. function _fd_read(fd, iov, iovcnt, pnum) {try {
  5925.  
  5926. var stream = SYSCALLS.getStreamFromFD(fd);
  5927. var num = SYSCALLS.doReadv(stream, iov, iovcnt);
  5928. HEAP32[((pnum)>>2)]=num
  5929. return 0;
  5930. } catch (e) {
  5931. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  5932. return e.errno;
  5933. }
  5934. }
  5935.  
  5936. function _fd_seek(fd, offset_low, offset_high, whence, newOffset) {try {
  5937.  
  5938.  
  5939. var stream = SYSCALLS.getStreamFromFD(fd);
  5940. var HIGH_OFFSET = 0x100000000; // 2^32
  5941. // use an unsigned operator on low and shift high by 32-bits
  5942. var offset = offset_high * HIGH_OFFSET + (offset_low >>> 0);
  5943.  
  5944. var DOUBLE_LIMIT = 0x20000000000000; // 2^53
  5945. // we also check for equality since DOUBLE_LIMIT + 1 == DOUBLE_LIMIT
  5946. if (offset <= -DOUBLE_LIMIT || offset >= DOUBLE_LIMIT) {
  5947. return -61;
  5948. }
  5949.  
  5950. FS.llseek(stream, offset, whence);
  5951. (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]);
  5952. if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; // reset readdir state
  5953. return 0;
  5954. } catch (e) {
  5955. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  5956. return e.errno;
  5957. }
  5958. }
  5959.  
  5960. function _fd_write(fd, iov, iovcnt, pnum) {try {
  5961.  
  5962. var stream = SYSCALLS.getStreamFromFD(fd);
  5963. var num = SYSCALLS.doWritev(stream, iov, iovcnt);
  5964. HEAP32[((pnum)>>2)]=num
  5965. return 0;
  5966. } catch (e) {
  5967. if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
  5968. return e.errno;
  5969. }
  5970. }
  5971.  
  5972. function _fork() {
  5973. // pid_t fork(void);
  5974. // http://pubs.opengroup.org/onlinepubs/000095399/functions/fork.html
  5975. // We don't support multiple processes.
  5976. setErrNo(6);
  5977. return -1;
  5978. }
  5979.  
  5980. function _getTempRet0() {
  5981. return (getTempRet0() | 0);
  5982. }
  5983.  
  5984. function _getpwnam() { throw 'getpwnam: TODO' }
  5985.  
  5986. function _getpwuid() { throw 'getpwuid: TODO' }
  5987.  
  5988. function _gettimeofday(ptr) {
  5989. var now = Date.now();
  5990. HEAP32[((ptr)>>2)]=(now/1000)|0; // seconds
  5991. HEAP32[(((ptr)+(4))>>2)]=((now % 1000)*1000)|0; // microseconds
  5992. return 0;
  5993. }
  5994.  
  5995.  
  5996. var ___tm_current=977648;
  5997.  
  5998.  
  5999. var ___tm_timezone=(stringToUTF8("GMT", 977696, 4), 977696);function _gmtime_r(time, tmPtr) {
  6000. var date = new Date(HEAP32[((time)>>2)]*1000);
  6001. HEAP32[((tmPtr)>>2)]=date.getUTCSeconds();
  6002. HEAP32[(((tmPtr)+(4))>>2)]=date.getUTCMinutes();
  6003. HEAP32[(((tmPtr)+(8))>>2)]=date.getUTCHours();
  6004. HEAP32[(((tmPtr)+(12))>>2)]=date.getUTCDate();
  6005. HEAP32[(((tmPtr)+(16))>>2)]=date.getUTCMonth();
  6006. HEAP32[(((tmPtr)+(20))>>2)]=date.getUTCFullYear()-1900;
  6007. HEAP32[(((tmPtr)+(24))>>2)]=date.getUTCDay();
  6008. HEAP32[(((tmPtr)+(36))>>2)]=0;
  6009. HEAP32[(((tmPtr)+(32))>>2)]=0;
  6010. var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0);
  6011. var yday = ((date.getTime() - start) / (1000 * 60 * 60 * 24))|0;
  6012. HEAP32[(((tmPtr)+(28))>>2)]=yday;
  6013. HEAP32[(((tmPtr)+(40))>>2)]=___tm_timezone;
  6014.  
  6015. return tmPtr;
  6016. }function _gmtime(time) {
  6017. return _gmtime_r(time, ___tm_current);
  6018. }
  6019.  
  6020.  
  6021.  
  6022. function _tzset() {
  6023. // TODO: Use (malleable) environment variables instead of system settings.
  6024. if (_tzset.called) return;
  6025. _tzset.called = true;
  6026.  
  6027. // timezone is specified as seconds west of UTC ("The external variable
  6028. // `timezone` shall be set to the difference, in seconds, between
  6029. // Coordinated Universal Time (UTC) and local standard time."), the same
  6030. // as returned by getTimezoneOffset().
  6031. // See http://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html
  6032. HEAP32[((__get_timezone())>>2)]=(new Date()).getTimezoneOffset() * 60;
  6033.  
  6034. var currentYear = new Date().getFullYear();
  6035. var winter = new Date(currentYear, 0, 1);
  6036. var summer = new Date(currentYear, 6, 1);
  6037. HEAP32[((__get_daylight())>>2)]=Number(winter.getTimezoneOffset() != summer.getTimezoneOffset());
  6038.  
  6039. function extractZone(date) {
  6040. var match = date.toTimeString().match(/\(([A-Za-z ]+)\)$/);
  6041. return match ? match[1] : "GMT";
  6042. };
  6043. var winterName = extractZone(winter);
  6044. var summerName = extractZone(summer);
  6045. var winterNamePtr = allocateUTF8(winterName);
  6046. var summerNamePtr = allocateUTF8(summerName);
  6047. if (summer.getTimezoneOffset() < winter.getTimezoneOffset()) {
  6048. // Northern hemisphere
  6049. HEAP32[((__get_tzname())>>2)]=winterNamePtr;
  6050. HEAP32[(((__get_tzname())+(4))>>2)]=summerNamePtr;
  6051. } else {
  6052. HEAP32[((__get_tzname())>>2)]=summerNamePtr;
  6053. HEAP32[(((__get_tzname())+(4))>>2)]=winterNamePtr;
  6054. }
  6055. }function _localtime_r(time, tmPtr) {
  6056. _tzset();
  6057. var date = new Date(HEAP32[((time)>>2)]*1000);
  6058. HEAP32[((tmPtr)>>2)]=date.getSeconds();
  6059. HEAP32[(((tmPtr)+(4))>>2)]=date.getMinutes();
  6060. HEAP32[(((tmPtr)+(8))>>2)]=date.getHours();
  6061. HEAP32[(((tmPtr)+(12))>>2)]=date.getDate();
  6062. HEAP32[(((tmPtr)+(16))>>2)]=date.getMonth();
  6063. HEAP32[(((tmPtr)+(20))>>2)]=date.getFullYear()-1900;
  6064. HEAP32[(((tmPtr)+(24))>>2)]=date.getDay();
  6065.  
  6066. var start = new Date(date.getFullYear(), 0, 1);
  6067. var yday = ((date.getTime() - start.getTime()) / (1000 * 60 * 60 * 24))|0;
  6068. HEAP32[(((tmPtr)+(28))>>2)]=yday;
  6069. HEAP32[(((tmPtr)+(36))>>2)]=-(date.getTimezoneOffset() * 60);
  6070.  
  6071. // Attention: DST is in December in South, and some regions don't have DST at all.
  6072. var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset();
  6073. var winterOffset = start.getTimezoneOffset();
  6074. var dst = (summerOffset != winterOffset && date.getTimezoneOffset() == Math.min(winterOffset, summerOffset))|0;
  6075. HEAP32[(((tmPtr)+(32))>>2)]=dst;
  6076.  
  6077. var zonePtr = HEAP32[(((__get_tzname())+(dst ? 4 : 0))>>2)];
  6078. HEAP32[(((tmPtr)+(40))>>2)]=zonePtr;
  6079.  
  6080. return tmPtr;
  6081. }function _localtime(time) {
  6082. return _localtime_r(time, ___tm_current);
  6083. }
  6084.  
  6085.  
  6086.  
  6087. var _emscripten_get_now;if (ENVIRONMENT_IS_NODE) {
  6088. _emscripten_get_now = function() {
  6089. var t = process['hrtime']();
  6090. return t[0] * 1e3 + t[1] / 1e6;
  6091. };
  6092. } else if (typeof dateNow !== 'undefined') {
  6093. _emscripten_get_now = dateNow;
  6094. } else _emscripten_get_now = function() { return performance.now(); }
  6095. ;function _usleep(useconds) {
  6096. // int usleep(useconds_t useconds);
  6097. // http://pubs.opengroup.org/onlinepubs/000095399/functions/usleep.html
  6098. // We're single-threaded, so use a busy loop. Super-ugly.
  6099. var start = _emscripten_get_now();
  6100. while (_emscripten_get_now() - start < useconds / 1000) {
  6101. // Do nothing.
  6102. }
  6103. }
  6104. Module["_usleep"] = _usleep;function _nanosleep(rqtp, rmtp) {
  6105. // int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
  6106. if (rqtp === 0) {
  6107. setErrNo(28);
  6108. return -1;
  6109. }
  6110. var seconds = HEAP32[((rqtp)>>2)];
  6111. var nanoseconds = HEAP32[(((rqtp)+(4))>>2)];
  6112. if (nanoseconds < 0 || nanoseconds > 999999999 || seconds < 0) {
  6113. setErrNo(28);
  6114. return -1;
  6115. }
  6116. if (rmtp !== 0) {
  6117. HEAP32[((rmtp)>>2)]=0;
  6118. HEAP32[(((rmtp)+(4))>>2)]=0;
  6119. }
  6120. return _usleep((seconds * 1e6) + (nanoseconds / 1000));
  6121. }
  6122.  
  6123. /** @type {function(...*):?} */
  6124. function _popen(
  6125. ) {
  6126. err('missing function: popen'); abort(-1);
  6127. }
  6128.  
  6129.  
  6130. function _setTempRet0($i) {
  6131. setTempRet0(($i) | 0);
  6132. }
  6133.  
  6134.  
  6135. var __sigalrm_handler=0;function _signal(sig, func) {
  6136. if (sig == 14 /*SIGALRM*/) {
  6137. __sigalrm_handler = func;
  6138. } else {
  6139. }
  6140. return 0;
  6141. }
  6142.  
  6143.  
  6144. function __isLeapYear(year) {
  6145. return year%4 === 0 && (year%100 !== 0 || year%400 === 0);
  6146. }
  6147.  
  6148. function __arraySum(array, index) {
  6149. var sum = 0;
  6150. for (var i = 0; i <= index; sum += array[i++]) {
  6151. // no-op
  6152. }
  6153. return sum;
  6154. }
  6155.  
  6156.  
  6157. var __MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];
  6158.  
  6159. var __MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];function __addDays(date, days) {
  6160. var newDate = new Date(date.getTime());
  6161. while(days > 0) {
  6162. var leap = __isLeapYear(newDate.getFullYear());
  6163. var currentMonth = newDate.getMonth();
  6164. var daysInCurrentMonth = (leap ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR)[currentMonth];
  6165.  
  6166. if (days > daysInCurrentMonth-newDate.getDate()) {
  6167. // we spill over to next month
  6168. days -= (daysInCurrentMonth-newDate.getDate()+1);
  6169. newDate.setDate(1);
  6170. if (currentMonth < 11) {
  6171. newDate.setMonth(currentMonth+1)
  6172. } else {
  6173. newDate.setMonth(0);
  6174. newDate.setFullYear(newDate.getFullYear()+1);
  6175. }
  6176. } else {
  6177. // we stay in current month
  6178. newDate.setDate(newDate.getDate()+days);
  6179. return newDate;
  6180. }
  6181. }
  6182.  
  6183. return newDate;
  6184. }function _strftime(s, maxsize, format, tm) {
  6185. // size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, const struct tm *restrict timeptr);
  6186. // http://pubs.opengroup.org/onlinepubs/009695399/functions/strftime.html
  6187.  
  6188. var tm_zone = HEAP32[(((tm)+(40))>>2)];
  6189.  
  6190. var date = {
  6191. tm_sec: HEAP32[((tm)>>2)],
  6192. tm_min: HEAP32[(((tm)+(4))>>2)],
  6193. tm_hour: HEAP32[(((tm)+(8))>>2)],
  6194. tm_mday: HEAP32[(((tm)+(12))>>2)],
  6195. tm_mon: HEAP32[(((tm)+(16))>>2)],
  6196. tm_year: HEAP32[(((tm)+(20))>>2)],
  6197. tm_wday: HEAP32[(((tm)+(24))>>2)],
  6198. tm_yday: HEAP32[(((tm)+(28))>>2)],
  6199. tm_isdst: HEAP32[(((tm)+(32))>>2)],
  6200. tm_gmtoff: HEAP32[(((tm)+(36))>>2)],
  6201. tm_zone: tm_zone ? UTF8ToString(tm_zone) : ''
  6202. };
  6203.  
  6204. var pattern = UTF8ToString(format);
  6205.  
  6206. // expand format
  6207. var EXPANSION_RULES_1 = {
  6208. '%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
  6209. '%D': '%m/%d/%y', // Equivalent to %m / %d / %y
  6210. '%F': '%Y-%m-%d', // Equivalent to %Y - %m - %d
  6211. '%h': '%b', // Equivalent to %b
  6212. '%r': '%I:%M:%S %p', // Replaced by the time in a.m. and p.m. notation
  6213. '%R': '%H:%M', // Replaced by the time in 24-hour notation
  6214. '%T': '%H:%M:%S', // Replaced by the time
  6215. '%x': '%m/%d/%y', // Replaced by the locale's appropriate date representation
  6216. '%X': '%H:%M:%S', // Replaced by the locale's appropriate time representation
  6217. // Modified Conversion Specifiers
  6218. '%Ec': '%c', // Replaced by the locale's alternative appropriate date and time representation.
  6219. '%EC': '%C', // Replaced by the name of the base year (period) in the locale's alternative representation.
  6220. '%Ex': '%m/%d/%y', // Replaced by the locale's alternative date representation.
  6221. '%EX': '%H:%M:%S', // Replaced by the locale's alternative time representation.
  6222. '%Ey': '%y', // Replaced by the offset from %EC (year only) in the locale's alternative representation.
  6223. '%EY': '%Y', // Replaced by the full alternative year representation.
  6224. '%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.
  6225. '%Oe': '%e', // Replaced by the day of the month, using the locale's alternative numeric symbols, filled as needed with leading <space> characters.
  6226. '%OH': '%H', // Replaced by the hour (24-hour clock) using the locale's alternative numeric symbols.
  6227. '%OI': '%I', // Replaced by the hour (12-hour clock) using the locale's alternative numeric symbols.
  6228. '%Om': '%m', // Replaced by the month using the locale's alternative numeric symbols.
  6229. '%OM': '%M', // Replaced by the minutes using the locale's alternative numeric symbols.
  6230. '%OS': '%S', // Replaced by the seconds using the locale's alternative numeric symbols.
  6231. '%Ou': '%u', // Replaced by the weekday as a number in the locale's alternative representation (Monday=1).
  6232. '%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.
  6233. '%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.
  6234. '%Ow': '%w', // Replaced by the number of the weekday (Sunday=0) using the locale's alternative numeric symbols.
  6235. '%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.
  6236. '%Oy': '%y', // Replaced by the year (offset from %C ) using the locale's alternative numeric symbols.
  6237. };
  6238. for (var rule in EXPANSION_RULES_1) {
  6239. pattern = pattern.replace(new RegExp(rule, 'g'), EXPANSION_RULES_1[rule]);
  6240. }
  6241.  
  6242. var WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
  6243. var MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
  6244.  
  6245. function leadingSomething(value, digits, character) {
  6246. var str = typeof value === 'number' ? value.toString() : (value || '');
  6247. while (str.length < digits) {
  6248. str = character[0]+str;
  6249. }
  6250. return str;
  6251. }
  6252.  
  6253. function leadingNulls(value, digits) {
  6254. return leadingSomething(value, digits, '0');
  6255. }
  6256.  
  6257. function compareByDay(date1, date2) {
  6258. function sgn(value) {
  6259. return value < 0 ? -1 : (value > 0 ? 1 : 0);
  6260. }
  6261.  
  6262. var compare;
  6263. if ((compare = sgn(date1.getFullYear()-date2.getFullYear())) === 0) {
  6264. if ((compare = sgn(date1.getMonth()-date2.getMonth())) === 0) {
  6265. compare = sgn(date1.getDate()-date2.getDate());
  6266. }
  6267. }
  6268. return compare;
  6269. }
  6270.  
  6271. function getFirstWeekStartDate(janFourth) {
  6272. switch (janFourth.getDay()) {
  6273. case 0: // Sunday
  6274. return new Date(janFourth.getFullYear()-1, 11, 29);
  6275. case 1: // Monday
  6276. return janFourth;
  6277. case 2: // Tuesday
  6278. return new Date(janFourth.getFullYear(), 0, 3);
  6279. case 3: // Wednesday
  6280. return new Date(janFourth.getFullYear(), 0, 2);
  6281. case 4: // Thursday
  6282. return new Date(janFourth.getFullYear(), 0, 1);
  6283. case 5: // Friday
  6284. return new Date(janFourth.getFullYear()-1, 11, 31);
  6285. case 6: // Saturday
  6286. return new Date(janFourth.getFullYear()-1, 11, 30);
  6287. }
  6288. }
  6289.  
  6290. function getWeekBasedYear(date) {
  6291. var thisDate = __addDays(new Date(date.tm_year+1900, 0, 1), date.tm_yday);
  6292.  
  6293. var janFourthThisYear = new Date(thisDate.getFullYear(), 0, 4);
  6294. var janFourthNextYear = new Date(thisDate.getFullYear()+1, 0, 4);
  6295.  
  6296. var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear);
  6297. var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear);
  6298.  
  6299. if (compareByDay(firstWeekStartThisYear, thisDate) <= 0) {
  6300. // this date is after the start of the first week of this year
  6301. if (compareByDay(firstWeekStartNextYear, thisDate) <= 0) {
  6302. return thisDate.getFullYear()+1;
  6303. } else {
  6304. return thisDate.getFullYear();
  6305. }
  6306. } else {
  6307. return thisDate.getFullYear()-1;
  6308. }
  6309. }
  6310.  
  6311. var EXPANSION_RULES_2 = {
  6312. '%a': function(date) {
  6313. return WEEKDAYS[date.tm_wday].substring(0,3);
  6314. },
  6315. '%A': function(date) {
  6316. return WEEKDAYS[date.tm_wday];
  6317. },
  6318. '%b': function(date) {
  6319. return MONTHS[date.tm_mon].substring(0,3);
  6320. },
  6321. '%B': function(date) {
  6322. return MONTHS[date.tm_mon];
  6323. },
  6324. '%C': function(date) {
  6325. var year = date.tm_year+1900;
  6326. return leadingNulls((year/100)|0,2);
  6327. },
  6328. '%d': function(date) {
  6329. return leadingNulls(date.tm_mday, 2);
  6330. },
  6331. '%e': function(date) {
  6332. return leadingSomething(date.tm_mday, 2, ' ');
  6333. },
  6334. '%g': function(date) {
  6335. // %g, %G, and %V give values according to the ISO 8601:2000 standard week-based year.
  6336. // In this system, weeks begin on a Monday and week 1 of the year is the week that includes
  6337. // January 4th, which is also the week that includes the first Thursday of the year, and
  6338. // is also the first week that contains at least four days in the year.
  6339. // If the first Monday of January is the 2nd, 3rd, or 4th, the preceding days are part of
  6340. // the last week of the preceding year; thus, for Saturday 2nd January 1999,
  6341. // %G is replaced by 1998 and %V is replaced by 53. If December 29th, 30th,
  6342. // or 31st is a Monday, it and any following days are part of week 1 of the following year.
  6343. // Thus, for Tuesday 30th December 1997, %G is replaced by 1998 and %V is replaced by 01.
  6344.  
  6345. return getWeekBasedYear(date).toString().substring(2);
  6346. },
  6347. '%G': function(date) {
  6348. return getWeekBasedYear(date);
  6349. },
  6350. '%H': function(date) {
  6351. return leadingNulls(date.tm_hour, 2);
  6352. },
  6353. '%I': function(date) {
  6354. var twelveHour = date.tm_hour;
  6355. if (twelveHour == 0) twelveHour = 12;
  6356. else if (twelveHour > 12) twelveHour -= 12;
  6357. return leadingNulls(twelveHour, 2);
  6358. },
  6359. '%j': function(date) {
  6360. // Day of the year (001-366)
  6361. return leadingNulls(date.tm_mday+__arraySum(__isLeapYear(date.tm_year+1900) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, date.tm_mon-1), 3);
  6362. },
  6363. '%m': function(date) {
  6364. return leadingNulls(date.tm_mon+1, 2);
  6365. },
  6366. '%M': function(date) {
  6367. return leadingNulls(date.tm_min, 2);
  6368. },
  6369. '%n': function() {
  6370. return '\n';
  6371. },
  6372. '%p': function(date) {
  6373. if (date.tm_hour >= 0 && date.tm_hour < 12) {
  6374. return 'AM';
  6375. } else {
  6376. return 'PM';
  6377. }
  6378. },
  6379. '%S': function(date) {
  6380. return leadingNulls(date.tm_sec, 2);
  6381. },
  6382. '%t': function() {
  6383. return '\t';
  6384. },
  6385. '%u': function(date) {
  6386. return date.tm_wday || 7;
  6387. },
  6388. '%U': function(date) {
  6389. // Replaced by the week number of the year as a decimal number [00,53].
  6390. // The first Sunday of January is the first day of week 1;
  6391. // days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
  6392. var janFirst = new Date(date.tm_year+1900, 0, 1);
  6393. var firstSunday = janFirst.getDay() === 0 ? janFirst : __addDays(janFirst, 7-janFirst.getDay());
  6394. var endDate = new Date(date.tm_year+1900, date.tm_mon, date.tm_mday);
  6395.  
  6396. // is target date after the first Sunday?
  6397. if (compareByDay(firstSunday, endDate) < 0) {
  6398. // calculate difference in days between first Sunday and endDate
  6399. var februaryFirstUntilEndMonth = __arraySum(__isLeapYear(endDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, endDate.getMonth()-1)-31;
  6400. var firstSundayUntilEndJanuary = 31-firstSunday.getDate();
  6401. var days = firstSundayUntilEndJanuary+februaryFirstUntilEndMonth+endDate.getDate();
  6402. return leadingNulls(Math.ceil(days/7), 2);
  6403. }
  6404.  
  6405. return compareByDay(firstSunday, janFirst) === 0 ? '01': '00';
  6406. },
  6407. '%V': function(date) {
  6408. // Replaced by the week number of the year (Monday as the first day of the week)
  6409. // as a decimal number [01,53]. If the week containing 1 January has four
  6410. // or more days in the new year, then it is considered week 1.
  6411. // Otherwise, it is the last week of the previous year, and the next week is week 1.
  6412. // Both January 4th and the first Thursday of January are always in week 1. [ tm_year, tm_wday, tm_yday]
  6413. var janFourthThisYear = new Date(date.tm_year+1900, 0, 4);
  6414. var janFourthNextYear = new Date(date.tm_year+1901, 0, 4);
  6415.  
  6416. var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear);
  6417. var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear);
  6418.  
  6419. var endDate = __addDays(new Date(date.tm_year+1900, 0, 1), date.tm_yday);
  6420.  
  6421. if (compareByDay(endDate, firstWeekStartThisYear) < 0) {
  6422. // if given date is before this years first week, then it belongs to the 53rd week of last year
  6423. return '53';
  6424. }
  6425.  
  6426. if (compareByDay(firstWeekStartNextYear, endDate) <= 0) {
  6427. // if given date is after next years first week, then it belongs to the 01th week of next year
  6428. return '01';
  6429. }
  6430.  
  6431. // given date is in between CW 01..53 of this calendar year
  6432. var daysDifference;
  6433. if (firstWeekStartThisYear.getFullYear() < date.tm_year+1900) {
  6434. // first CW of this year starts last year
  6435. daysDifference = date.tm_yday+32-firstWeekStartThisYear.getDate()
  6436. } else {
  6437. // first CW of this year starts this year
  6438. daysDifference = date.tm_yday+1-firstWeekStartThisYear.getDate();
  6439. }
  6440. return leadingNulls(Math.ceil(daysDifference/7), 2);
  6441. },
  6442. '%w': function(date) {
  6443. return date.tm_wday;
  6444. },
  6445. '%W': function(date) {
  6446. // Replaced by the week number of the year as a decimal number [00,53].
  6447. // The first Monday of January is the first day of week 1;
  6448. // days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
  6449. var janFirst = new Date(date.tm_year, 0, 1);
  6450. var firstMonday = janFirst.getDay() === 1 ? janFirst : __addDays(janFirst, janFirst.getDay() === 0 ? 1 : 7-janFirst.getDay()+1);
  6451. var endDate = new Date(date.tm_year+1900, date.tm_mon, date.tm_mday);
  6452.  
  6453. // is target date after the first Monday?
  6454. if (compareByDay(firstMonday, endDate) < 0) {
  6455. var februaryFirstUntilEndMonth = __arraySum(__isLeapYear(endDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, endDate.getMonth()-1)-31;
  6456. var firstMondayUntilEndJanuary = 31-firstMonday.getDate();
  6457. var days = firstMondayUntilEndJanuary+februaryFirstUntilEndMonth+endDate.getDate();
  6458. return leadingNulls(Math.ceil(days/7), 2);
  6459. }
  6460. return compareByDay(firstMonday, janFirst) === 0 ? '01': '00';
  6461. },
  6462. '%y': function(date) {
  6463. // Replaced by the last two digits of the year as a decimal number [00,99]. [ tm_year]
  6464. return (date.tm_year+1900).toString().substring(2);
  6465. },
  6466. '%Y': function(date) {
  6467. // Replaced by the year as a decimal number (for example, 1997). [ tm_year]
  6468. return date.tm_year+1900;
  6469. },
  6470. '%z': function(date) {
  6471. // Replaced by the offset from UTC in the ISO 8601:2000 standard format ( +hhmm or -hhmm ).
  6472. // For example, "-0430" means 4 hours 30 minutes behind UTC (west of Greenwich).
  6473. var off = date.tm_gmtoff;
  6474. var ahead = off >= 0;
  6475. off = Math.abs(off) / 60;
  6476. // convert from minutes into hhmm format (which means 60 minutes = 100 units)
  6477. off = (off / 60)*100 + (off % 60);
  6478. return (ahead ? '+' : '-') + String("0000" + off).slice(-4);
  6479. },
  6480. '%Z': function(date) {
  6481. return date.tm_zone;
  6482. },
  6483. '%%': function() {
  6484. return '%';
  6485. }
  6486. };
  6487. for (var rule in EXPANSION_RULES_2) {
  6488. if (pattern.indexOf(rule) >= 0) {
  6489. pattern = pattern.replace(new RegExp(rule, 'g'), EXPANSION_RULES_2[rule](date));
  6490. }
  6491. }
  6492.  
  6493. var bytes = intArrayFromString(pattern, false);
  6494. if (bytes.length > maxsize) {
  6495. return 0;
  6496. }
  6497.  
  6498. writeArrayToMemory(bytes, s);
  6499. return bytes.length-1;
  6500. }
  6501.  
  6502. function _system(command) {
  6503. if (ENVIRONMENT_IS_NODE) {
  6504. if (!command) return 1; // shell is available
  6505.  
  6506. var cmdstr = UTF8ToString(command);
  6507. if (!cmdstr.length) return 0; // this is what glibc seems to do (shell works test?)
  6508.  
  6509. var cp = require('child_process');
  6510. var ret = cp.spawnSync(cmdstr, [], {shell:true, stdio:'inherit'});
  6511.  
  6512. var _W_EXITCODE = function(ret, sig) {
  6513. return ((ret) << 8 | (sig));
  6514. }
  6515.  
  6516. // this really only can happen if process is killed by signal
  6517. if (ret.status === null) {
  6518. // sadly node doesn't expose such function
  6519. var signalToNumber = function(sig) {
  6520. // implement only the most common ones, and fallback to SIGINT
  6521. switch (sig) {
  6522. case 'SIGHUP': return 1;
  6523. case 'SIGINT': return 2;
  6524. case 'SIGQUIT': return 3;
  6525. case 'SIGFPE': return 8;
  6526. case 'SIGKILL': return 9;
  6527. case 'SIGALRM': return 14;
  6528. case 'SIGTERM': return 15;
  6529. }
  6530. return 2; // SIGINT
  6531. }
  6532. return _W_EXITCODE(0, signalToNumber(ret.signal));
  6533. }
  6534.  
  6535. return _W_EXITCODE(ret.status, 0);
  6536. }
  6537. // int system(const char *command);
  6538. // http://pubs.opengroup.org/onlinepubs/000095399/functions/system.html
  6539. // Can't call external programs.
  6540. if (!command) return 0; // no shell available
  6541. setErrNo(6);
  6542. return -1;
  6543. }
  6544.  
  6545.  
  6546. function _time(ptr) {
  6547. var ret = (Date.now()/1000)|0;
  6548. if (ptr) {
  6549. HEAP32[((ptr)>>2)]=ret;
  6550. }
  6551. return ret;
  6552. }
  6553.  
  6554. function _wait(stat_loc) {
  6555. // pid_t wait(int *stat_loc);
  6556. // http://pubs.opengroup.org/onlinepubs/009695399/functions/wait.html
  6557. // Makes no sense in a single-process environment.
  6558. setErrNo(12);
  6559. return -1;
  6560. }
  6561. var FSNode = /** @constructor */ function(parent, name, mode, rdev) {
  6562. if (!parent) {
  6563. parent = this; // root node sets parent to itself
  6564. }
  6565. this.parent = parent;
  6566. this.mount = parent.mount;
  6567. this.mounted = null;
  6568. this.id = FS.nextInode++;
  6569. this.name = name;
  6570. this.mode = mode;
  6571. this.node_ops = {};
  6572. this.stream_ops = {};
  6573. this.rdev = rdev;
  6574. };
  6575. var readMode = 292/*292*/ | 73/*73*/;
  6576. var writeMode = 146/*146*/;
  6577. Object.defineProperties(FSNode.prototype, {
  6578. read: {
  6579. get: /** @this{FSNode} */function() {
  6580. return (this.mode & readMode) === readMode;
  6581. },
  6582. set: /** @this{FSNode} */function(val) {
  6583. val ? this.mode |= readMode : this.mode &= ~readMode;
  6584. }
  6585. },
  6586. write: {
  6587. get: /** @this{FSNode} */function() {
  6588. return (this.mode & writeMode) === writeMode;
  6589. },
  6590. set: /** @this{FSNode} */function(val) {
  6591. val ? this.mode |= writeMode : this.mode &= ~writeMode;
  6592. }
  6593. },
  6594. isFolder: {
  6595. get: /** @this{FSNode} */function() {
  6596. return FS.isDir(this.mode);
  6597. }
  6598. },
  6599. isDevice: {
  6600. get: /** @this{FSNode} */function() {
  6601. return FS.isChrdev(this.mode);
  6602. }
  6603. }
  6604. });
  6605. FS.FSNode = FSNode;
  6606. FS.staticInit();;
  6607. var ASSERTIONS = false;
  6608.  
  6609. /**
  6610. * @license
  6611. * Copyright 2017 The Emscripten Authors
  6612. * SPDX-License-Identifier: MIT
  6613. */
  6614.  
  6615. /** @type {function(string, boolean=, number=)} */
  6616. function intArrayFromString(stringy, dontAddNull, length) {
  6617. var len = length > 0 ? length : lengthBytesUTF8(stringy)+1;
  6618. var u8array = new Array(len);
  6619. var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
  6620. if (dontAddNull) u8array.length = numBytesWritten;
  6621. return u8array;
  6622. }
  6623.  
  6624. function intArrayToString(array) {
  6625. var ret = [];
  6626. for (var i = 0; i < array.length; i++) {
  6627. var chr = array[i];
  6628. if (chr > 0xFF) {
  6629. if (ASSERTIONS) {
  6630. assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ') at offset ' + i + ' not in 0x00-0xFF.');
  6631. }
  6632. chr &= 0xFF;
  6633. }
  6634. ret.push(String.fromCharCode(chr));
  6635. }
  6636. return ret.join('');
  6637. }
  6638.  
  6639.  
  6640. var asmGlobalArg = {};
  6641. var asmLibraryArg = { "__assert_fail": ___assert_fail, "__sys_access": ___sys_access, "__sys_dup": ___sys_dup, "__sys_fcntl64": ___sys_fcntl64, "__sys_getcwd": ___sys_getcwd, "__sys_getdents64": ___sys_getdents64, "__sys_getpid": ___sys_getpid, "__sys_getuid32": ___sys_getuid32, "__sys_ioctl": ___sys_ioctl, "__sys_lstat64": ___sys_lstat64, "__sys_open": ___sys_open, "__sys_pipe": ___sys_pipe, "__sys_read": ___sys_read, "__sys_readlink": ___sys_readlink, "__sys_rename": ___sys_rename, "__sys_rmdir": ___sys_rmdir, "__sys_socketcall": ___sys_socketcall, "__sys_stat64": ___sys_stat64, "__sys_unlink": ___sys_unlink, "__sys_wait4": ___sys_wait4, "__wait": ___wait, "_exit": __exit, "abort": _abort, "emscripten_get_sbrk_ptr": _emscripten_get_sbrk_ptr, "emscripten_longjmp": _emscripten_longjmp, "emscripten_memcpy_big": _emscripten_memcpy_big, "emscripten_resize_heap": _emscripten_resize_heap, "environ_get": _environ_get, "environ_sizes_get": _environ_sizes_get, "execvp": _execvp, "exit": _exit, "fd_close": _fd_close, "fd_read": _fd_read, "fd_seek": _fd_seek, "fd_write": _fd_write, "fork": _fork, "getTempRet0": _getTempRet0, "getpwnam": _getpwnam, "getpwuid": _getpwuid, "gettimeofday": _gettimeofday, "gmtime": _gmtime, "invoke_i": invoke_i, "invoke_id": invoke_id, "invoke_ii": invoke_ii, "invoke_iii": invoke_iii, "invoke_iiii": invoke_iiii, "invoke_iiiii": invoke_iiiii, "invoke_vii": invoke_vii, "invoke_viiii": invoke_viiii, "localtime": _localtime, "memory": wasmMemory, "nanosleep": _nanosleep, "popen": _popen, "saveSetjmp": _saveSetjmp, "setTempRet0": _setTempRet0, "signal": _signal, "strftime": _strftime, "system": _system, "table": wasmTable, "testSetjmp": _testSetjmp, "time": _time, "wait": _wait };
  6642. var asm = createWasm();
  6643. Module["asm"] = asm;
  6644. /** @type {function(...*):?} */
  6645. var ___wasm_call_ctors = Module["___wasm_call_ctors"] = function() {
  6646. return (___wasm_call_ctors = Module["___wasm_call_ctors"] = Module["asm"]["__wasm_call_ctors"]).apply(null, arguments);
  6647. };
  6648.  
  6649. /** @type {function(...*):?} */
  6650. var _free = Module["_free"] = function() {
  6651. return (_free = Module["_free"] = Module["asm"]["free"]).apply(null, arguments);
  6652. };
  6653.  
  6654. /** @type {function(...*):?} */
  6655. var _main = Module["_main"] = function() {
  6656. return (_main = Module["_main"] = Module["asm"]["main"]).apply(null, arguments);
  6657. };
  6658.  
  6659. /** @type {function(...*):?} */
  6660. var ___errno_location = Module["___errno_location"] = function() {
  6661. return (___errno_location = Module["___errno_location"] = Module["asm"]["__errno_location"]).apply(null, arguments);
  6662. };
  6663.  
  6664. /** @type {function(...*):?} */
  6665. var _malloc = Module["_malloc"] = function() {
  6666. return (_malloc = Module["_malloc"] = Module["asm"]["malloc"]).apply(null, arguments);
  6667. };
  6668.  
  6669. /** @type {function(...*):?} */
  6670. var _realloc = Module["_realloc"] = function() {
  6671. return (_realloc = Module["_realloc"] = Module["asm"]["realloc"]).apply(null, arguments);
  6672. };
  6673.  
  6674. /** @type {function(...*):?} */
  6675. var _ntohs = Module["_ntohs"] = function() {
  6676. return (_ntohs = Module["_ntohs"] = Module["asm"]["ntohs"]).apply(null, arguments);
  6677. };
  6678.  
  6679. /** @type {function(...*):?} */
  6680. var _htons = Module["_htons"] = function() {
  6681. return (_htons = Module["_htons"] = Module["asm"]["htons"]).apply(null, arguments);
  6682. };
  6683.  
  6684. /** @type {function(...*):?} */
  6685. var _htonl = Module["_htonl"] = function() {
  6686. return (_htonl = Module["_htonl"] = Module["asm"]["htonl"]).apply(null, arguments);
  6687. };
  6688.  
  6689. /** @type {function(...*):?} */
  6690. var __get_tzname = Module["__get_tzname"] = function() {
  6691. return (__get_tzname = Module["__get_tzname"] = Module["asm"]["_get_tzname"]).apply(null, arguments);
  6692. };
  6693.  
  6694. /** @type {function(...*):?} */
  6695. var __get_daylight = Module["__get_daylight"] = function() {
  6696. return (__get_daylight = Module["__get_daylight"] = Module["asm"]["_get_daylight"]).apply(null, arguments);
  6697. };
  6698.  
  6699. /** @type {function(...*):?} */
  6700. var __get_timezone = Module["__get_timezone"] = function() {
  6701. return (__get_timezone = Module["__get_timezone"] = Module["asm"]["_get_timezone"]).apply(null, arguments);
  6702. };
  6703.  
  6704. /** @type {function(...*):?} */
  6705. var _setThrew = Module["_setThrew"] = function() {
  6706. return (_setThrew = Module["_setThrew"] = Module["asm"]["setThrew"]).apply(null, arguments);
  6707. };
  6708.  
  6709. /** @type {function(...*):?} */
  6710. var dynCall_vii = Module["dynCall_vii"] = function() {
  6711. return (dynCall_vii = Module["dynCall_vii"] = Module["asm"]["dynCall_vii"]).apply(null, arguments);
  6712. };
  6713.  
  6714. /** @type {function(...*):?} */
  6715. var dynCall_viiii = Module["dynCall_viiii"] = function() {
  6716. return (dynCall_viiii = Module["dynCall_viiii"] = Module["asm"]["dynCall_viiii"]).apply(null, arguments);
  6717. };
  6718.  
  6719. /** @type {function(...*):?} */
  6720. var dynCall_i = Module["dynCall_i"] = function() {
  6721. return (dynCall_i = Module["dynCall_i"] = Module["asm"]["dynCall_i"]).apply(null, arguments);
  6722. };
  6723.  
  6724. /** @type {function(...*):?} */
  6725. var dynCall_ii = Module["dynCall_ii"] = function() {
  6726. return (dynCall_ii = Module["dynCall_ii"] = Module["asm"]["dynCall_ii"]).apply(null, arguments);
  6727. };
  6728.  
  6729. /** @type {function(...*):?} */
  6730. var dynCall_iii = Module["dynCall_iii"] = function() {
  6731. return (dynCall_iii = Module["dynCall_iii"] = Module["asm"]["dynCall_iii"]).apply(null, arguments);
  6732. };
  6733.  
  6734. /** @type {function(...*):?} */
  6735. var dynCall_iiii = Module["dynCall_iiii"] = function() {
  6736. return (dynCall_iiii = Module["dynCall_iiii"] = Module["asm"]["dynCall_iiii"]).apply(null, arguments);
  6737. };
  6738.  
  6739. /** @type {function(...*):?} */
  6740. var dynCall_iiiii = Module["dynCall_iiiii"] = function() {
  6741. return (dynCall_iiiii = Module["dynCall_iiiii"] = Module["asm"]["dynCall_iiiii"]).apply(null, arguments);
  6742. };
  6743.  
  6744. /** @type {function(...*):?} */
  6745. var dynCall_id = Module["dynCall_id"] = function() {
  6746. return (dynCall_id = Module["dynCall_id"] = Module["asm"]["dynCall_id"]).apply(null, arguments);
  6747. };
  6748.  
  6749. /** @type {function(...*):?} */
  6750. var stackSave = Module["stackSave"] = function() {
  6751. return (stackSave = Module["stackSave"] = Module["asm"]["stackSave"]).apply(null, arguments);
  6752. };
  6753.  
  6754. /** @type {function(...*):?} */
  6755. var stackAlloc = Module["stackAlloc"] = function() {
  6756. return (stackAlloc = Module["stackAlloc"] = Module["asm"]["stackAlloc"]).apply(null, arguments);
  6757. };
  6758.  
  6759. /** @type {function(...*):?} */
  6760. var stackRestore = Module["stackRestore"] = function() {
  6761. return (stackRestore = Module["stackRestore"] = Module["asm"]["stackRestore"]).apply(null, arguments);
  6762. };
  6763.  
  6764. /** @type {function(...*):?} */
  6765. var __growWasmMemory = Module["__growWasmMemory"] = function() {
  6766. return (__growWasmMemory = Module["__growWasmMemory"] = Module["asm"]["__growWasmMemory"]).apply(null, arguments);
  6767. };
  6768.  
  6769. /** @type {function(...*):?} */
  6770. var dynCall_vi = Module["dynCall_vi"] = function() {
  6771. return (dynCall_vi = Module["dynCall_vi"] = Module["asm"]["dynCall_vi"]).apply(null, arguments);
  6772. };
  6773.  
  6774. /** @type {function(...*):?} */
  6775. var dynCall_viii = Module["dynCall_viii"] = function() {
  6776. return (dynCall_viii = Module["dynCall_viii"] = Module["asm"]["dynCall_viii"]).apply(null, arguments);
  6777. };
  6778.  
  6779. /** @type {function(...*):?} */
  6780. var dynCall_viiiii = Module["dynCall_viiiii"] = function() {
  6781. return (dynCall_viiiii = Module["dynCall_viiiii"] = Module["asm"]["dynCall_viiiii"]).apply(null, arguments);
  6782. };
  6783.  
  6784. /** @type {function(...*):?} */
  6785. var dynCall_v = Module["dynCall_v"] = function() {
  6786. return (dynCall_v = Module["dynCall_v"] = Module["asm"]["dynCall_v"]).apply(null, arguments);
  6787. };
  6788.  
  6789. /** @type {function(...*):?} */
  6790. var dynCall_iiiiiiiiiiii = Module["dynCall_iiiiiiiiiiii"] = function() {
  6791. return (dynCall_iiiiiiiiiiii = Module["dynCall_iiiiiiiiiiii"] = Module["asm"]["dynCall_iiiiiiiiiiii"]).apply(null, arguments);
  6792. };
  6793.  
  6794. /** @type {function(...*):?} */
  6795. var dynCall_ji = Module["dynCall_ji"] = function() {
  6796. return (dynCall_ji = Module["dynCall_ji"] = Module["asm"]["dynCall_ji"]).apply(null, arguments);
  6797. };
  6798.  
  6799. /** @type {function(...*):?} */
  6800. var dynCall_viji = Module["dynCall_viji"] = function() {
  6801. return (dynCall_viji = Module["dynCall_viji"] = Module["asm"]["dynCall_viji"]).apply(null, arguments);
  6802. };
  6803.  
  6804. /** @type {function(...*):?} */
  6805. var dynCall_iijiji = Module["dynCall_iijiji"] = function() {
  6806. return (dynCall_iijiji = Module["dynCall_iijiji"] = Module["asm"]["dynCall_iijiji"]).apply(null, arguments);
  6807. };
  6808.  
  6809. /** @type {function(...*):?} */
  6810. var dynCall_jiji = Module["dynCall_jiji"] = function() {
  6811. return (dynCall_jiji = Module["dynCall_jiji"] = Module["asm"]["dynCall_jiji"]).apply(null, arguments);
  6812. };
  6813.  
  6814. /** @type {function(...*):?} */
  6815. var dynCall_iidiiii = Module["dynCall_iidiiii"] = function() {
  6816. return (dynCall_iidiiii = Module["dynCall_iidiiii"] = Module["asm"]["dynCall_iidiiii"]).apply(null, arguments);
  6817. };
  6818.  
  6819. /** @type {function(...*):?} */
  6820. var dynCall_viiiiii = Module["dynCall_viiiiii"] = function() {
  6821. return (dynCall_viiiiii = Module["dynCall_viiiiii"] = Module["asm"]["dynCall_viiiiii"]).apply(null, arguments);
  6822. };
  6823.  
  6824.  
  6825. function invoke_iii(index,a1,a2) {
  6826. var sp = stackSave();
  6827. try {
  6828. return dynCall_iii(index,a1,a2);
  6829. } catch(e) {
  6830. stackRestore(sp);
  6831. if (e !== e+0 && e !== 'longjmp') throw e;
  6832. _setThrew(1, 0);
  6833. }
  6834. }
  6835.  
  6836. function invoke_iiiii(index,a1,a2,a3,a4) {
  6837. var sp = stackSave();
  6838. try {
  6839. return dynCall_iiiii(index,a1,a2,a3,a4);
  6840. } catch(e) {
  6841. stackRestore(sp);
  6842. if (e !== e+0 && e !== 'longjmp') throw e;
  6843. _setThrew(1, 0);
  6844. }
  6845. }
  6846.  
  6847. function invoke_vii(index,a1,a2) {
  6848. var sp = stackSave();
  6849. try {
  6850. dynCall_vii(index,a1,a2);
  6851. } catch(e) {
  6852. stackRestore(sp);
  6853. if (e !== e+0 && e !== 'longjmp') throw e;
  6854. _setThrew(1, 0);
  6855. }
  6856. }
  6857.  
  6858. function invoke_ii(index,a1) {
  6859. var sp = stackSave();
  6860. try {
  6861. return dynCall_ii(index,a1);
  6862. } catch(e) {
  6863. stackRestore(sp);
  6864. if (e !== e+0 && e !== 'longjmp') throw e;
  6865. _setThrew(1, 0);
  6866. }
  6867. }
  6868.  
  6869. function invoke_iiii(index,a1,a2,a3) {
  6870. var sp = stackSave();
  6871. try {
  6872. return dynCall_iiii(index,a1,a2,a3);
  6873. } catch(e) {
  6874. stackRestore(sp);
  6875. if (e !== e+0 && e !== 'longjmp') throw e;
  6876. _setThrew(1, 0);
  6877. }
  6878. }
  6879.  
  6880. function invoke_id(index,a1) {
  6881. var sp = stackSave();
  6882. try {
  6883. return dynCall_id(index,a1);
  6884. } catch(e) {
  6885. stackRestore(sp);
  6886. if (e !== e+0 && e !== 'longjmp') throw e;
  6887. _setThrew(1, 0);
  6888. }
  6889. }
  6890.  
  6891. function invoke_i(index) {
  6892. var sp = stackSave();
  6893. try {
  6894. return dynCall_i(index);
  6895. } catch(e) {
  6896. stackRestore(sp);
  6897. if (e !== e+0 && e !== 'longjmp') throw e;
  6898. _setThrew(1, 0);
  6899. }
  6900. }
  6901.  
  6902. function invoke_viiii(index,a1,a2,a3,a4) {
  6903. var sp = stackSave();
  6904. try {
  6905. dynCall_viiii(index,a1,a2,a3,a4);
  6906. } catch(e) {
  6907. stackRestore(sp);
  6908. if (e !== e+0 && e !== 'longjmp') throw e;
  6909. _setThrew(1, 0);
  6910. }
  6911. }
  6912.  
  6913.  
  6914. /**
  6915. * @license
  6916. * Copyright 2010 The Emscripten Authors
  6917. * SPDX-License-Identifier: MIT
  6918. */
  6919.  
  6920. // === Auto-generated postamble setup entry stuff ===
  6921.  
  6922. Module['asm'] = asm;
  6923.  
  6924.  
  6925.  
  6926.  
  6927.  
  6928.  
  6929.  
  6930.  
  6931.  
  6932.  
  6933.  
  6934.  
  6935.  
  6936.  
  6937.  
  6938.  
  6939.  
  6940.  
  6941.  
  6942.  
  6943.  
  6944.  
  6945.  
  6946.  
  6947.  
  6948.  
  6949.  
  6950.  
  6951.  
  6952.  
  6953.  
  6954.  
  6955.  
  6956.  
  6957.  
  6958.  
  6959.  
  6960.  
  6961.  
  6962.  
  6963.  
  6964.  
  6965.  
  6966.  
  6967.  
  6968.  
  6969.  
  6970.  
  6971.  
  6972.  
  6973.  
  6974.  
  6975.  
  6976.  
  6977.  
  6978.  
  6979.  
  6980.  
  6981.  
  6982.  
  6983.  
  6984.  
  6985.  
  6986.  
  6987.  
  6988.  
  6989.  
  6990.  
  6991.  
  6992.  
  6993.  
  6994.  
  6995.  
  6996.  
  6997.  
  6998.  
  6999.  
  7000.  
  7001.  
  7002.  
  7003.  
  7004.  
  7005.  
  7006.  
  7007.  
  7008.  
  7009.  
  7010.  
  7011.  
  7012.  
  7013.  
  7014.  
  7015.  
  7016.  
  7017.  
  7018.  
  7019.  
  7020.  
  7021.  
  7022.  
  7023.  
  7024.  
  7025.  
  7026.  
  7027.  
  7028.  
  7029.  
  7030.  
  7031.  
  7032.  
  7033.  
  7034.  
  7035.  
  7036.  
  7037.  
  7038.  
  7039.  
  7040.  
  7041.  
  7042.  
  7043.  
  7044.  
  7045.  
  7046.  
  7047.  
  7048.  
  7049.  
  7050.  
  7051.  
  7052.  
  7053.  
  7054.  
  7055.  
  7056.  
  7057.  
  7058.  
  7059. var calledRun;
  7060.  
  7061. /**
  7062. * @constructor
  7063. * @this {ExitStatus}
  7064. */
  7065. function ExitStatus(status) {
  7066. this.name = "ExitStatus";
  7067. this.message = "Program terminated with exit(" + status + ")";
  7068. this.status = status;
  7069. }
  7070.  
  7071. var calledMain = false;
  7072.  
  7073.  
  7074. dependenciesFulfilled = function runCaller() {
  7075. // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
  7076. if (!calledRun) run();
  7077. if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
  7078. };
  7079.  
  7080. function callMain(args) {
  7081.  
  7082. var entryFunction = Module['_main'];
  7083.  
  7084.  
  7085. args = args || [];
  7086.  
  7087. var argc = args.length+1;
  7088. var argv = stackAlloc((argc + 1) * 4);
  7089. HEAP32[argv >> 2] = allocateUTF8OnStack(thisProgram);
  7090. for (var i = 1; i < argc; i++) {
  7091. HEAP32[(argv >> 2) + i] = allocateUTF8OnStack(args[i - 1]);
  7092. }
  7093. HEAP32[(argv >> 2) + argc] = 0;
  7094.  
  7095.  
  7096. try {
  7097.  
  7098.  
  7099. var ret = entryFunction(argc, argv);
  7100.  
  7101.  
  7102. // In PROXY_TO_PTHREAD builds, we should never exit the runtime below, as execution is asynchronously handed
  7103. // off to a pthread.
  7104. // if we're not running an evented main loop, it's time to exit
  7105. exit(ret, /* implicit = */ true);
  7106. }
  7107. catch(e) {
  7108. if (e instanceof ExitStatus) {
  7109. // exit() throws this once it's done to make sure execution
  7110. // has been stopped completely
  7111. return;
  7112. } else if (e == 'unwind') {
  7113. // running an evented main loop, don't immediately exit
  7114. noExitRuntime = true;
  7115. return;
  7116. } else {
  7117. var toLog = e;
  7118. if (e && typeof e === 'object' && e.stack) {
  7119. toLog = [e, e.stack];
  7120. }
  7121. err('exception thrown: ' + toLog);
  7122. quit_(1, e);
  7123. }
  7124. } finally {
  7125. calledMain = true;
  7126. }
  7127. }
  7128.  
  7129.  
  7130.  
  7131.  
  7132. /** @type {function(Array=)} */
  7133. function run(args) {
  7134. args = args || arguments_;
  7135.  
  7136. if (runDependencies > 0) {
  7137. return;
  7138. }
  7139.  
  7140.  
  7141. preRun();
  7142.  
  7143. if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
  7144.  
  7145. function doRun() {
  7146. // run may have just been called through dependencies being fulfilled just in this very frame,
  7147. // or while the async setStatus time below was happening
  7148. if (calledRun) return;
  7149. calledRun = true;
  7150. Module['calledRun'] = true;
  7151.  
  7152. if (ABORT) return;
  7153.  
  7154. initRuntime();
  7155.  
  7156. preMain();
  7157.  
  7158. if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized']();
  7159.  
  7160. if (shouldRunNow) callMain(args);
  7161.  
  7162. postRun();
  7163. }
  7164.  
  7165. if (Module['setStatus']) {
  7166. Module['setStatus']('Running...');
  7167. setTimeout(function() {
  7168. setTimeout(function() {
  7169. Module['setStatus']('');
  7170. }, 1);
  7171. doRun();
  7172. }, 1);
  7173. } else
  7174. {
  7175. doRun();
  7176. }
  7177. }
  7178. Module['run'] = run;
  7179.  
  7180.  
  7181. /** @param {boolean|number=} implicit */
  7182. function exit(status, implicit) {
  7183.  
  7184. // if this is just main exit-ing implicitly, and the status is 0, then we
  7185. // don't need to do anything here and can just leave. if the status is
  7186. // non-zero, though, then we need to report it.
  7187. // (we may have warned about this earlier, if a situation justifies doing so)
  7188. if (implicit && noExitRuntime && status === 0) {
  7189. return;
  7190. }
  7191.  
  7192. if (noExitRuntime) {
  7193. } else {
  7194.  
  7195. ABORT = true;
  7196. EXITSTATUS = status;
  7197.  
  7198. exitRuntime();
  7199.  
  7200. if (Module['onExit']) Module['onExit'](status);
  7201. }
  7202.  
  7203. quit_(status, new ExitStatus(status));
  7204. }
  7205.  
  7206. if (Module['preInit']) {
  7207. if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
  7208. while (Module['preInit'].length > 0) {
  7209. Module['preInit'].pop()();
  7210. }
  7211. }
  7212.  
  7213. // shouldRunNow refers to calling main(), not run().
  7214. var shouldRunNow = true;
  7215.  
  7216. if (Module['noInitialRun']) shouldRunNow = false;
  7217.  
  7218.  
  7219. noExitRuntime = true;
  7220.  
  7221. run();
  7222.  
  7223.  
  7224.  
  7225.  
  7226.  
  7227. // {{MODULE_ADDITIONS}}
Add Comment
Please, Sign In to add comment