Advertisement
Guest User

Untitled

a guest
Aug 6th, 2011
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 47.95 KB | None | 0 0
  1. "use strict";
  2.  
  3. /*
  4. // Capture the output of this into a variable, if you want
  5. (function(Module, args) {
  6. Module = Module || {};
  7. Module.arguments = args || [];
  8. */
  9.  
  10. ///*
  11. // Runs much faster, for some reason
  12. if (!this['Module']) {
  13. this['Module'] = {};
  14. }
  15. if (!Module.arguments) {
  16. try {
  17. Module.arguments = scriptArgs;
  18. } catch(e) {
  19. try {
  20. Module.arguments = arguments;
  21. } catch(e) {
  22. Module.arguments = [];
  23. }
  24. }
  25. }
  26. //*/
  27.  
  28.  
  29. // === Auto-generated preamble library stuff ===
  30.  
  31. //========================================
  32. // Runtime code shared with compiler
  33. //========================================
  34.  
  35. var Runtime = {
  36. forceAlign: function (target, quantum) {
  37. quantum = quantum || 4;
  38. if (isNumber(target) && isNumber(quantum)) {
  39. return Math.ceil(target/quantum)*quantum;
  40. } else {
  41. return 'Math.ceil((' + target + ')/' + quantum + ')*' + quantum;
  42. }
  43. },
  44. isNumberType: function (type) {
  45. return type in Runtime.INT_TYPES || type in Runtime.FLOAT_TYPES;
  46. },
  47. isPointerType: function isPointerType(type) {
  48. return pointingLevels(type) > 0;
  49. },
  50. isStructType: function isStructType(type) {
  51. if (isPointerType(type)) return false;
  52. if (new RegExp(/^\[\d+\ x\ (.*)\]/g).test(type)) return true; // [15 x ?] blocks. Like structs
  53. // See comment in isStructPointerType()
  54. return !Runtime.isNumberType(type) && type[0] == '%';
  55. },
  56. INT_TYPES: {"i1":0,"i8":0,"i16":0,"i32":0,"i64":0},
  57. FLOAT_TYPES: {"float":0,"double":0},
  58. or64: function (x, y) {
  59. var l = (x | 0) | (y | 0);
  60. var h = (Math.round(x / 4294967296) | Math.round(y / 4294967296)) * 4294967296;
  61. return l + h;
  62. },
  63. and64: function (x, y) {
  64. var l = (x | 0) & (y | 0);
  65. var h = (Math.round(x / 4294967296) & Math.round(y / 4294967296)) * 4294967296;
  66. return l + h;
  67. },
  68. xor64: function (x, y) {
  69. var l = (x | 0) ^ (y | 0);
  70. var h = (Math.round(x / 4294967296) ^ Math.round(y / 4294967296)) * 4294967296;
  71. return l + h;
  72. },
  73. getNativeFieldSize: function getNativeFieldSize(type) {
  74. return Math.max(Runtime.getNativeTypeSize(type), 4);
  75. },
  76. getNativeTypeSize: function getNativeTypeSize(type) {
  77. if (4 == 1) return 1;
  78. var size = {
  79. '_i1': 1,
  80. '_i8': 1,
  81. '_i16': 2,
  82. '_i32': 4,
  83. '_i64': 8,
  84. "_float": 4,
  85. "_double": 8
  86. }['_'+type]; // add '_' since float&double confuse Closure compiler as keys.
  87. if (!size && type[type.length-1] == '*') {
  88. size = 4; // A pointer
  89. }
  90. return size;
  91. },
  92. dedup: function dedup(items, ident) {
  93. var seen = {};
  94. if (ident) {
  95. return items.filter(function(item) {
  96. if (seen[item[ident]]) return false;
  97. seen[item[ident]] = true;
  98. return true;
  99. });
  100. } else {
  101. return items.filter(function(item) {
  102. if (seen[item]) return false;
  103. seen[item] = true;
  104. return true;
  105. });
  106. }
  107. },
  108. set: function set() {
  109. var args = typeof arguments[0] === 'object' ? arguments[0] : arguments;
  110. var ret = {};
  111. for (var i = 0; i < args.length; i++) {
  112. ret[args[i]] = 0;
  113. }
  114. return ret;
  115. },
  116. calculateStructAlignment: function calculateStructAlignment(type) {
  117. type.flatSize = 0;
  118. type.alignSize = 0;
  119. var diffs = [];
  120. var prev = -1;
  121. type.flatIndexes = type.fields.map(function(field) {
  122. var size, alignSize;
  123. if (Runtime.isNumberType(field) || Runtime.isPointerType(field)) {
  124. size = Runtime.getNativeTypeSize(field); // pack char; char; in structs, also char[X]s.
  125. alignSize = size;
  126. } else if (Runtime.isStructType(field)) {
  127. size = Types.types[field].flatSize;
  128. alignSize = Types.types[field].alignSize;
  129. } else {
  130. dprint('Unclear type in struct: ' + field + ', in ' + type.name_);
  131. assert(0);
  132. }
  133. alignSize = type.packed ? 1 : Math.min(alignSize, 4);
  134. type.alignSize = Math.max(type.alignSize, alignSize);
  135. var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory
  136. type.flatSize = curr + size;
  137. if (prev >= 0) {
  138. diffs.push(curr-prev);
  139. }
  140. prev = curr;
  141. return curr;
  142. });
  143. type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize);
  144. if (diffs.length == 0) {
  145. type.flatFactor = type.flatSize;
  146. } else if (Runtime.dedup(diffs).length == 1) {
  147. type.flatFactor = diffs[0];
  148. }
  149. type.needsFlattening = (type.flatFactor != 1);
  150. return type.flatIndexes;
  151. },
  152. generateStructInfo: function (struct, typeName, offset) {
  153. var type, alignment;
  154. if (typeName) {
  155. offset = offset || 0;
  156. type = typeof Types === 'undefined' ? Runtime.typeInfo[typeName] : Types.types[typeName];
  157. if (!type) return null;
  158. if (!struct) struct = Types.structMetadata[typeName.replace(/.*\./, '')];
  159. if (!struct) return null;
  160. assert(type.fields.length === struct.length, 'Number of named fields must match the type for ' + typeName);
  161. alignment = type.flatIndexes;
  162. } else {
  163. var type = { fields: struct.map(function(item) { return item[0] }) };
  164. alignment = Runtime.calculateStructAlignment(type);
  165. }
  166. var ret = {
  167. __size__: type.flatSize
  168. };
  169. if (typeName) {
  170. struct.forEach(function(item, i) {
  171. if (typeof item === 'string') {
  172. ret[item] = alignment[i] + offset;
  173. } else {
  174. // embedded struct
  175. var key;
  176. for (var k in item) key = k;
  177. ret[key] = Runtime.generateStructInfo(item[key], type.fields[i], alignment[i]);
  178. }
  179. });
  180. } else {
  181. struct.forEach(function(item, i) {
  182. ret[item[1]] = alignment[i];
  183. });
  184. }
  185. return ret;
  186. },
  187. stackAlloc: function stackAlloc(size) { var ret = STACKTOP; assert(size > 0, "Trying to allocate 0"); _memset(STACKTOP, 0, size); STACKTOP += size;STACKTOP = Math.ceil((STACKTOP)/4)*4;; assert(STACKTOP < STACK_ROOT + STACK_MAX, "Ran out of stack"); return ret; },
  188. staticAlloc: function staticAlloc(size) { var ret = STATICTOP; assert(size > 0, "Trying to allocate 0"); STATICTOP += size;STATICTOP = Math.ceil((STATICTOP)/4)*4;; return ret; },
  189. alignMemory: function alignMemory(size,quantum) { var ret = size = Math.ceil((size)/(quantum ? quantum : 4))*(quantum ? quantum : 4);; return ret; },
  190. __dummy__: 0
  191. }
  192.  
  193.  
  194.  
  195. var CorrectionsMonitor = {
  196. MAX_ALLOWED: 0, // XXX
  197. corrections: 0,
  198. sigs: {},
  199.  
  200. note: function(type, succeed, sig) {
  201. if (!succeed) {
  202. this.corrections++;
  203. if (this.corrections >= this.MAX_ALLOWED) abort('\n\nToo many corrections!');
  204. }
  205. },
  206.  
  207. print: function() {
  208. var items = [];
  209. for (var sig in this.sigs) {
  210. items.push({
  211. sig: sig,
  212. fails: this.sigs[sig][0],
  213. succeeds: this.sigs[sig][1],
  214. total: this.sigs[sig][0] + this.sigs[sig][1]
  215. });
  216. }
  217. items.sort(function(x, y) { return y.total - x.total; });
  218. for (var i = 0; i < items.length; i++) {
  219. var item = items[i];
  220. print(item.sig + ' : ' + item.total + ' hits, %' + (Math.floor(100*item.fails/item.total)) + ' failures');
  221. }
  222. }
  223. };
  224.  
  225. function cRound(x) {
  226. return x >= 0 ? Math.floor(x) : Math.ceil(x);
  227. }
  228.  
  229.  
  230.  
  231.  
  232. //========================================
  233. // Runtime essentials
  234. //========================================
  235.  
  236. var __globalConstructor__ = function globalConstructor() {
  237. };
  238.  
  239. var __THREW__ = false; // Used in checking for thrown exceptions.
  240.  
  241. var __ATEXIT__ = [];
  242.  
  243. var ABORT = false;
  244.  
  245. var undef = 0;
  246.  
  247. function abort(text) {
  248. print(text + ':\n' + (new Error).stack);
  249. ABORT = true;
  250. throw "Assertion: " + text;
  251. }
  252.  
  253. function assert(condition, text) {
  254. if (!condition) {
  255. abort('Assertion failed: ' + text);
  256. }
  257. }
  258.  
  259. // Sets a value in memory in a dynamic way at run-time. Uses the
  260. // type data. This is the same as makeSetValue, except that
  261. // makeSetValue is done at compile-time and generates the needed
  262. // code then, whereas this function picks the right code at
  263. // run-time.
  264.  
  265. function setValue(ptr, value, type) {
  266. if (type[type.length-1] === '*') type = 'i32'; // pointers are 32-bit
  267. switch(type) {
  268. case 'i1': HEAP[ptr]=value;; break;
  269. case 'i8': HEAP[ptr]=value;; break;
  270. case 'i16': HEAP[ptr]=value;; break;
  271. case 'i32': HEAP[ptr]=value;; break;
  272. case 'i64': HEAP[ptr]=value;; break;
  273. case 'float': HEAP[ptr]=value;; break;
  274. case 'double': HEAP[ptr]=value;; break;
  275. default: abort('invalid type for setValue: ' + type);
  276. }
  277. }
  278.  
  279. // Parallel to setValue.
  280.  
  281. function getValue(ptr, type) {
  282. if (type[type.length-1] === '*') type = 'i32'; // pointers are 32-bit
  283. switch(type) {
  284. case 'i1': return HEAP[ptr];
  285. case 'i8': return HEAP[ptr];
  286. case 'i16': return HEAP[ptr];
  287. case 'i32': return HEAP[ptr];
  288. case 'i64': return HEAP[ptr];
  289. case 'float': return HEAP[ptr];
  290. case 'double': return HEAP[ptr];
  291. default: abort('invalid type for setValue: ' + type);
  292. }
  293. return null;
  294. }
  295.  
  296. // Allocates memory for some data and initializes it properly.
  297.  
  298. var ALLOC_NORMAL = 0; // Tries to use _malloc()
  299. var ALLOC_STACK = 1; // Lives for the duration of the current function call
  300. var ALLOC_STATIC = 2; // Cannot be freed
  301.  
  302. function allocate(slab, types, allocator) {
  303. var zeroinit, size;
  304. if (typeof slab === 'number') {
  305. zeroinit = true;
  306. size = slab;
  307. } else {
  308. zeroinit = false;
  309. size = slab.length;
  310. }
  311.  
  312. var ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, 1));
  313.  
  314. var singleType = typeof types === 'string' ? types : null;
  315.  
  316. var i = 0, type;
  317. while (i < size) {
  318. var curr = zeroinit ? 0 : slab[i];
  319.  
  320. if (typeof curr === 'function') {
  321. curr = Runtime.getFunctionIndex(curr);
  322. }
  323.  
  324. type = singleType || types[i];
  325. if (type === 0) {
  326. i++;
  327. continue;
  328. }
  329. assert(type, 'Must know what type to store in allocate!');
  330.  
  331. setValue(ret+i, curr, type);
  332. i += Runtime.getNativeTypeSize(type);
  333. }
  334.  
  335. return ret;
  336. }
  337. Module['allocate'] = allocate;
  338.  
  339. function Pointer_stringify(ptr) {
  340. var ret = "";
  341. var i = 0;
  342. var t;
  343. while (1) {
  344. t = String.fromCharCode(HEAP[ptr+i]);
  345. if (t == "\0") { break; } else {}
  346. ret += t;
  347. i += 1;
  348. }
  349. return ret;
  350. }
  351.  
  352. function Array_stringify(array) {
  353. var ret = "";
  354. for (var i = 0; i < array.length; i++) {
  355. ret += String.fromCharCode(array[i]);
  356. }
  357. return ret;
  358. }
  359.  
  360. // Memory management
  361.  
  362. var PAGE_SIZE = 4096;
  363. function alignMemoryPage(x) {
  364. return Math.ceil(x/PAGE_SIZE)*PAGE_SIZE;
  365. }
  366.  
  367. var HEAP;
  368.  
  369. var STACK_ROOT, STACKTOP, STACK_MAX;
  370. var STATICTOP;
  371.  
  372. var HAS_TYPED_ARRAYS = false;
  373. var TOTAL_MEMORY = 50*1024*1024;
  374.  
  375. // Initialize the runtime's memory
  376. {
  377. // Without this optimization, Chrome is slow. Sadly, the constant here needs to be tweaked depending on the code being run...
  378. var FAST_MEMORY = TOTAL_MEMORY/32;
  379. HEAP = new Array(FAST_MEMORY);
  380. for (var i = 0; i < FAST_MEMORY; i++) {
  381. HEAP[i] = 0; // XXX We do *not* use {{| makeSetValue(0, 'i', 0, 'null') |}} here, since this is done just to optimize runtime speed
  382. }
  383. }
  384.  
  385. var base = intArrayFromString('(null)'); // So printing %s of NULL gives '(null)'
  386. // Also this ensures we leave 0 as an invalid address, 'NULL'
  387. for (var i = 0; i < base.length; i++) {
  388. HEAP[i]=base[i];
  389. }
  390.  
  391. Module['HEAP'] = HEAP;
  392.  
  393. STACK_ROOT = STACKTOP = alignMemoryPage(10);
  394. var TOTAL_STACK = 1024*1024; // XXX: Changing this value can lead to bad perf on v8!
  395. STACK_MAX = STACK_ROOT + TOTAL_STACK;
  396.  
  397. STATICTOP = alignMemoryPage(STACK_MAX);
  398.  
  399. function __shutdownRuntime__() {
  400. while(__ATEXIT__.length > 0) {
  401. var atexit = __ATEXIT__.pop();
  402. var func = atexit.func;
  403. if (typeof func === 'number') {
  404. func = FUNCTION_TABLE[func];
  405. }
  406. func(atexit.arg === undefined ? null : atexit.arg);
  407. }
  408.  
  409. // allow browser to GC, set heaps to null?
  410.  
  411. // Print summary of correction activity
  412. CorrectionsMonitor.print();
  413. }
  414.  
  415.  
  416. // Copies a list of num items on the HEAP into a
  417. // a normal JavaScript array of numbers
  418. function Array_copy(ptr, num) {
  419. // TODO: In the SAFE_HEAP case, do some reading here, for debugging purposes - currently this is an 'unnoticed read'.
  420. return HEAP.slice(ptr, ptr+num);
  421. }
  422.  
  423. function String_len(ptr) {
  424. var i = 0;
  425. while (HEAP[ptr+i]) i++; // Note: should be |!= 0|, technically. But this helps catch bugs with undefineds
  426. return i;
  427. }
  428.  
  429. // Copies a C-style string, terminated by a zero, from the HEAP into
  430. // a normal JavaScript array of numbers
  431. function String_copy(ptr, addZero) {
  432. var len = String_len(ptr);
  433. if (addZero) len++;
  434. var ret = Array_copy(ptr, len);
  435. if (addZero) ret[len-1] = 0;
  436. return ret;
  437. }
  438.  
  439. // Tools
  440.  
  441. if (typeof print === 'undefined') {
  442. print = console.log; // we are on the web
  443. }
  444.  
  445. // This processes a JS string into a C-line array of numbers, 0-terminated.
  446. // For LLVM-originating strings, see parser.js:parseLLVMString function
  447. function intArrayFromString(stringy, dontAddNull) {
  448. var ret = [];
  449. var t;
  450. var i = 0;
  451. while (i < stringy.length) {
  452. var chr = stringy.charCodeAt(i);
  453. if (chr > 0xFF) {
  454. assert(false, 'Character code ' + chr + ' (' + stringy[i] + ') at offset ' + i + ' not in 0x00-0xFF.');
  455. chr &= 0xFF;
  456. }
  457. ret.push(chr);
  458. i = i + 1;
  459. }
  460. if (!dontAddNull) {
  461. ret.push(0);
  462. }
  463. return ret;
  464. }
  465. Module['intArrayFromString'] = intArrayFromString;
  466.  
  467. function intArrayToString(array) {
  468. var ret = [];
  469. for (var i = 0; i < array.length; i++) {
  470. var chr = array[i];
  471. if (chr > 0xFF) {
  472. assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ') at offset ' + i + ' not in 0x00-0xFF.');
  473. chr &= 0xFF;
  474. }
  475. ret.push(String.fromCharCode(chr));
  476. }
  477. return ret.join('');
  478. }
  479.  
  480. function unSign(value, bits, ignore, sig) {
  481. if (value >= 0) {
  482. return value;
  483. }
  484. 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
  485. : Math.pow(2, bits) + value;
  486. // TODO: clean up previous line
  487. }
  488. function reSign(value, bits, ignore, sig) {
  489. if (value <= 0) {
  490. return value;
  491. }
  492. var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
  493. : Math.pow(2, bits-1);
  494. if (value >= half) {
  495. value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
  496. }
  497. return value;
  498. }
  499.  
  500. // === Body ===
  501.  
  502.  
  503.  
  504. var $struct_data___SIZE = 8; // %struct.data
  505.  
  506. var __str;
  507.  
  508.  
  509. var _memcpy=function _memcpy (dest, src, num, idunno) {
  510. assert(num % 1 === 0, 'memcpy given ' + num + ' bytes to copy. Problem with 4=1 corrections perhaps?');
  511. // || 0, since memcpy sometimes copies uninitialized areas XXX: Investigate why initializing alloc'ed memory does not fix that too
  512. for (var $mcpi$ = 0; $mcpi$ < num; $mcpi$++) {
  513. HEAP[dest+$mcpi$]=HEAP[src+$mcpi$];
  514. };
  515. };var _llvm_memcpy_p0i8_p0i8_i64=_memcpy;
  516.  
  517.  
  518.  
  519.  
  520.  
  521. var ERRNO_CODES={"E2BIG":7,"EACCES":13,"EADDRINUSE":98,"EADDRNOTAVAIL":99,"EAFNOSUPPORT":97,"EAGAIN":11,"EALREADY":114,"EBADF":9,"EBADMSG":74,"EBUSY":16,"ECANCELED":125,"ECHILD":10,"ECONNABORTED":103,"ECONNREFUSED":111,"ECONNRESET":104,"EDEADLK":35,"EDESTADDRREQ":89,"EDOM":33,"EDQUOT":122,"EEXIST":17,"EFAULT":14,"EFBIG":27,"EHOSTUNREACH":113,"EIDRM":43,"EILSEQ":84,"EINPROGRESS":115,"EINTR":4,"EINVAL":22,"EIO":5,"EISCONN":106,"EISDIR":21,"ELOOP":40,"EMFILE":24,"EMLINK":31,"EMSGSIZE":90,"EMULTIHOP":72,"ENAMETOOLONG":36,"ENETDOWN":100,"ENETRESET":102,"ENETUNREACH":101,"ENFILE":23,"ENOBUFS":105,"ENODATA":61,"ENODEV":19,"ENOENT":2,"ENOEXEC":8,"ENOLCK":37,"ENOLINK":67,"ENOMEM":12,"ENOMSG":42,"ENOPROTOOPT":92,"ENOSPC":28,"ENOSR":63,"ENOSTR":60,"ENOSYS":38,"ENOTCONN":107,"ENOTDIR":20,"ENOTEMPTY":39,"ENOTRECOVERABLE":131,"ENOTSOCK":88,"ENOTSUP":95,"ENOTTY":25,"ENXIO":6,"EOVERFLOW":75,"EOWNERDEAD":130,"EPERM":1,"EPIPE":32,"EPROTO":71,"EPROTONOSUPPORT":93,"EPROTOTYPE":91,"ERANGE":34,"EROFS":30,"ESPIPE":29,"ESRCH":3,"ESTALE":116,"ETIME":62,"ETIMEDOUT":110,"ETXTBSY":26,"EWOULDBLOCK":11,"EXDEV":18};
  522.  
  523. var ___setErrNo=function ___setErrNo (value) {
  524. // For convenient setting and returning of errno.
  525. var me = ___setErrNo;
  526. if (!me.ptr) me.ptr = allocate([0], 'i32', ALLOC_NORMAL);
  527. HEAP[me.ptr]=value;
  528. return value;
  529. };
  530.  
  531. var _stdin=0;
  532.  
  533. var _stdout=0;
  534.  
  535. var _stderr=0;var FS={"root":{"read":true,"write":false,"isFolder":true,"isDevice":false,"timestamp":1312660155623,"inodeNumber":1,"contents":{}},"currentPath":"/","nextInode":2,"streams":[null],"ignorePermissions":true, absolutePath: function (relative, base) {
  536. if (typeof relative !== 'string') return null;
  537. if (base === undefined) base = FS.currentPath;
  538. if (relative && relative[0] == '/') base = '';
  539. var full = base + '/' + relative;
  540. var parts = full.split('/').reverse();
  541. var absolute = [''];
  542. while (parts.length) {
  543. var part = parts.pop();
  544. if (part == '' || part == '.') {
  545. // Nothing.
  546. } else if (part == '..') {
  547. if (absolute.length > 1) absolute.pop();
  548. } else {
  549. absolute.push(part);
  550. }
  551. }
  552. return absolute.length == 1 ? '/' : absolute.join('/');
  553. }, analyzePath: function (path, dontResolveLastLink, linksVisited) {
  554. var ret = {
  555. isRoot: false,
  556. exists: false,
  557. error: 0,
  558. name: null,
  559. path: null,
  560. object: null,
  561. parentExists: false,
  562. parentPath: null,
  563. parentObject: null
  564. };
  565. path = FS.absolutePath(path);
  566. if (path == '/') {
  567. ret.isRoot = true;
  568. ret.exists = ret.parentExists = true;
  569. ret.name = '/';
  570. ret.path = ret.parentPath = '/';
  571. ret.object = ret.parentObject = FS.root;
  572. } else if (path !== null) {
  573. linksVisited = linksVisited || 0;
  574. path = path.slice(1).split('/');
  575. var current = FS.root;
  576. var traversed = [''];
  577. while (path.length) {
  578. if (path.length == 1 && current.isFolder) {
  579. ret.parentExists = true;
  580. ret.parentPath = traversed.length == 1 ? '/' : traversed.join('/');
  581. ret.parentObject = current;
  582. ret.name = path[0];
  583. }
  584. var target = path.shift();
  585. if (!current.isFolder) {
  586. ret.error = ERRNO_CODES.ENOTDIR;
  587. break;
  588. } else if (!current.read) {
  589. ret.error = ERRNO_CODES.EACCES;
  590. break;
  591. } else if (!current.contents.hasOwnProperty(target)) {
  592. ret.error = ERRNO_CODES.ENOENT;
  593. break;
  594. }
  595. current = current.contents[target];
  596. if (current.link && !(dontResolveLastLink && path.length == 0)) {
  597. if (linksVisited > 40) { // Usual Linux SYMLOOP_MAX.
  598. ret.error = ERRNO_CODES.ELOOP;
  599. break;
  600. }
  601. var link = FS.absolutePath(current.link, traversed.join('/'));
  602. return FS.analyzePath([link].concat(path).join('/'),
  603. dontResolveLastLink, linksVisited + 1);
  604. }
  605. traversed.push(target);
  606. if (path.length == 0) {
  607. ret.exists = true;
  608. ret.path = traversed.join('/');
  609. ret.object = current;
  610. }
  611. }
  612. return ret;
  613. }
  614. return ret;
  615. }, findObject: function (path, dontResolveLastLink) {
  616. var ret = FS.analyzePath(path, dontResolveLastLink);
  617. if (ret.exists) {
  618. return ret.object;
  619. } else {
  620. ___setErrNo(ret.error);
  621. return null;
  622. }
  623. }, createObject: function (parent, name, properties, canRead, canWrite) {
  624. if (!parent) parent = '/';
  625. if (typeof parent === 'string') parent = FS.findObject(parent);
  626.  
  627. if (!parent) {
  628. ___setErrNo(ERRNO_CODES.EACCES);
  629. throw new Error('Parent path must exist.');
  630. }
  631. if (!parent.isFolder) {
  632. ___setErrNo(ERRNO_CODES.ENOTDIR);
  633. throw new Error('Parent must be a folder.');
  634. }
  635. if (!parent.write && !FS.ignorePermissions) {
  636. ___setErrNo(ERRNO_CODES.EACCES);
  637. throw new Error('Parent folder must be writeable.');
  638. }
  639. if (!name || name == '.' || name == '..') {
  640. ___setErrNo(ERRNO_CODES.ENOENT);
  641. throw new Error('Name must not be empty.');
  642. }
  643. if (parent.contents.hasOwnProperty(name)) {
  644. ___setErrNo(ERRNO_CODES.EEXIST);
  645. throw new Error("Can't overwrite object.");
  646. }
  647.  
  648. parent.contents[name] = {
  649. read: canRead === undefined ? true : canRead,
  650. write: canWrite === undefined ? false : canWrite,
  651. timestamp: Date.now(),
  652. inodeNumber: FS.nextInode++
  653. };
  654. for (var key in properties) {
  655. if (properties.hasOwnProperty(key)) {
  656. parent.contents[name][key] = properties[key];
  657. }
  658. }
  659.  
  660. return parent.contents[name];
  661. }, createFolder: function (parent, name, canRead, canWrite) {
  662. var properties = {isFolder: true, isDevice: false, contents: {}};
  663. return FS.createObject(parent, name, properties, canRead, canWrite);
  664. }, createPath: function (parent, path, canRead, canWrite) {
  665. var current = FS.findObject(parent);
  666. if (current === null) throw new Error('Invalid parent.');
  667. path = path.split('/').reverse();
  668. while (path.length) {
  669. var part = path.pop();
  670. if (!part) continue;
  671. if (!current.contents.hasOwnProperty(part)) {
  672. FS.createFolder(current, part, canRead, canWrite);
  673. }
  674. current = current.contents[part];
  675. }
  676. return current;
  677. }, createFile: function (parent, name, properties, canRead, canWrite) {
  678. properties.isFolder = false;
  679. return FS.createObject(parent, name, properties, canRead, canWrite);
  680. }, createDataFile: function (parent, name, data, canRead, canWrite) {
  681. if (typeof data === 'string') {
  682. var dataArray = [];
  683. for (var i = 0; i < data.length; i++) dataArray.push(data.charCodeAt(i));
  684. data = dataArray;
  685. }
  686. var properties = {isDevice: false, contents: data};
  687. return FS.createFile(parent, name, properties, canRead, canWrite);
  688. }, createLazyFile: function (parent, name, url, canRead, canWrite) {
  689. var properties = {isDevice: false, url: url};
  690. return FS.createFile(parent, name, properties, canRead, canWrite);
  691. }, createLink: function (parent, name, target, canRead, canWrite) {
  692. var properties = {isDevice: false, link: target};
  693. return FS.createFile(parent, name, properties, canRead, canWrite);
  694. }, createDevice: function (parent, name, input, output) {
  695. if (!(input || output)) {
  696. throw new Error('A device must have at least one callback defined.');
  697. }
  698. var ops = {isDevice: true, input: input, output: output};
  699. return FS.createFile(parent, name, ops, Boolean(input), Boolean(output));
  700. }, forceLoadFile: function (obj) {
  701. if (obj.isDevice || obj.isFolder || obj.link ||
  702. 'contents' in obj) return true;
  703. var success = true;
  704. if (typeof XMLHttpRequest !== 'undefined') {
  705. // Browser.
  706. // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
  707. var xhr = new XMLHttpRequest();
  708. xhr.open('GET', obj.url, false);
  709. xhr.responseType = 'arraybuffer'; // hint to the browser that we want binary data
  710. xhr.overrideMimeType('text/plain; charset=x-user-defined'); // another hint
  711. xhr.send(null);
  712. if (xhr.status != 200 && xhr.status != 0) success = false;
  713. if (xhr.response !== undefined) {
  714. obj.contents = new Uint8Array(xhr.response || []);
  715. } else {
  716. obj.contents = intArrayFromString(xhr.responseText || '', true);
  717. }
  718. } else if (typeof read !== 'undefined') {
  719. // Command-line.
  720. try {
  721. // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
  722. // read() will try to parse UTF8.
  723. obj.contents = intArrayFromString(read(obj.url), true);
  724. } catch (e) {
  725. success = false;
  726. }
  727. } else {
  728. throw new Error('Cannot load without read() or XMLHttpRequest.');
  729. }
  730. if (!success) ___setErrNo(ERRNO_CODES.EIO);
  731. return success;
  732. }, init: function (input, output, error) {
  733. // Make sure we initialize only once.
  734. if (FS.init.initialized) return;
  735. else FS.init.initialized = true;
  736.  
  737. // Default handlers.
  738. if (!input) input = function() {
  739. if (!input.cache || !input.cache.length) {
  740. var result;
  741. if (window && typeof window.prompt == 'function') {
  742. // Browser.
  743. result = window.prompt('Input: ');
  744. } else if (typeof readline == 'function') {
  745. // Command line.
  746. result = readline();
  747. }
  748. if (!result) return null;
  749. input.cache = intArrayFromString(result + '\n', true);
  750. }
  751. return input.cache.shift();
  752. };
  753. if (!output) output = function(val) {
  754. if (!output.printer) {
  755. if (typeof print == 'function') {
  756. // Either console or custom print function defined.
  757. output.printer = print;
  758. } else if (console && typeof console.log == 'function') {
  759. // Browser-like environment with a console.
  760. output.printer = console.log;
  761. } else {
  762. // Fallback to a harmless no-op.
  763. output.printer = function() {};
  764. }
  765. }
  766. if (!output.buffer) output.buffer = [];
  767. if (val === null || val === '\n'.charCodeAt(0)) {
  768. output.printer(output.buffer.join(''));
  769. output.buffer = [];
  770. } else {
  771. output.buffer.push(String.fromCharCode(val));
  772. }
  773. };
  774. if (!error) error = output;
  775.  
  776. // Create the temporary folder.
  777. FS.createFolder('/', 'tmp', true, true);
  778.  
  779. // Create the I/O devices.
  780. var devFolder = FS.createFolder('/', 'dev', true, false);
  781. var stdin = FS.createDevice(devFolder, 'stdin', input);
  782. var stdout = FS.createDevice(devFolder, 'stdout', null, output);
  783. var stderr = FS.createDevice(devFolder, 'stderr', null, error);
  784. FS.createDevice(devFolder, 'tty', input, output);
  785.  
  786. // Create default streams.
  787. FS.streams[1] = {
  788. path: '/dev/stdin',
  789. object: stdin,
  790. position: 0,
  791. isRead: true,
  792. isWrite: false,
  793. isAppend: false,
  794. error: false,
  795. eof: false,
  796. ungotten: []
  797. };
  798. FS.streams[2] = {
  799. path: '/dev/stdout',
  800. object: stdout,
  801. position: 0,
  802. isRead: false,
  803. isWrite: true,
  804. isAppend: false,
  805. error: false,
  806. eof: false,
  807. ungotten: []
  808. };
  809. FS.streams[3] = {
  810. path: '/dev/stderr',
  811. object: stderr,
  812. position: 0,
  813. isRead: false,
  814. isWrite: true,
  815. isAppend: false,
  816. error: false,
  817. eof: false,
  818. ungotten: []
  819. };
  820. _stdin = allocate([1], 'void*', ALLOC_STATIC);
  821. _stdout = allocate([2], 'void*', ALLOC_STATIC);
  822. _stderr = allocate([3], 'void*', ALLOC_STATIC);
  823.  
  824. // Once initialized, permissions start having effect.
  825. FS.ignorePermissions = false;
  826. } };
  827.  
  828.  
  829.  
  830.  
  831.  
  832.  
  833.  
  834. var _pwrite=function _pwrite (fildes, buf, nbyte, offset) {
  835. // ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
  836. // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
  837. var stream = FS.streams[fildes];
  838. if (!stream || stream.object.isDevice) {
  839. ___setErrNo(ERRNO_CODES.EBADF);
  840. return -1;
  841. } else if (!stream.isWrite) {
  842. ___setErrNo(ERRNO_CODES.EACCES);
  843. return -1;
  844. } else if (stream.object.isFolder) {
  845. ___setErrNo(ERRNO_CODES.EISDIR);
  846. return -1;
  847. } else if (nbyte < 0 || offset < 0) {
  848. ___setErrNo(ERRNO_CODES.EINVAL);
  849. return -1;
  850. } else {
  851. var contents = stream.object.contents;
  852. while (contents.length < offset) contents.push(0);
  853. for (var i = 0; i < nbyte; i++) {
  854. contents[offset + i] = HEAP[buf+i];
  855. }
  856. stream.object.timestamp = Date.now();
  857. return i;
  858. }
  859. };var _write=function _write (fildes, buf, nbyte) {
  860. // ssize_t write(int fildes, const void *buf, size_t nbyte);
  861. // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
  862. var stream = FS.streams[fildes];
  863. if (!stream) {
  864. ___setErrNo(ERRNO_CODES.EBADF);
  865. return -1;
  866. } else if (!stream.isWrite) {
  867. ___setErrNo(ERRNO_CODES.EACCES);
  868. return -1;
  869. } else if (nbyte < 0) {
  870. ___setErrNo(ERRNO_CODES.EINVAL);
  871. return -1;
  872. } else {
  873. if (stream.object.isDevice) {
  874. if (stream.object.output) {
  875. for (var i = 0; i < nbyte; i++) {
  876. try {
  877. stream.object.output(HEAP[buf+i]);
  878. } catch (e) {
  879. ___setErrNo(ERRNO_CODES.EIO);
  880. return -1;
  881. }
  882. }
  883. stream.object.timestamp = Date.now();
  884. return i;
  885. } else {
  886. ___setErrNo(ERRNO_CODES.ENXIO);
  887. return -1;
  888. }
  889. } else {
  890. var bytesWritten = _pwrite(fildes, buf, nbyte, stream.position);
  891. if (bytesWritten != -1) stream.position += bytesWritten;
  892. return bytesWritten;
  893. }
  894. }
  895. };var _fwrite=function _fwrite (ptr, size, nitems, stream) {
  896. // size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
  897. // http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html
  898. var bytesToWrite = nitems * size;
  899. if (bytesToWrite == 0) return 0;
  900. var bytesWritten = _write(stream, ptr, bytesToWrite);
  901. if (bytesWritten == -1) {
  902. if (FS.streams[stream]) FS.streams[stream].error = true;
  903. return -1;
  904. } else {
  905. return Math.floor(bytesWritten / size);
  906. }
  907. };
  908.  
  909. var __formatString=function __formatString (isVarArgs, format/*, ...*/) {
  910. var textIndex = format;
  911. var argIndex = 0;
  912. var getNextArg;
  913. if (isVarArgs) {
  914. var varArgStart = arguments[2];
  915. getNextArg = function(type) {
  916. var ret;
  917. if (type === 'double') {
  918. ret = HEAP[varArgStart+argIndex];
  919. } else if (type === 'float') {
  920. ret = HEAP[varArgStart+argIndex];
  921. } else if (type === 'i64') {
  922. ret = HEAP[varArgStart+argIndex];
  923. } else if (type === 'i32') {
  924. ret = HEAP[varArgStart+argIndex];
  925. } else if (type === 'i16') {
  926. ret = HEAP[varArgStart+argIndex];
  927. } else if (type === 'i8') {
  928. ret = HEAP[varArgStart+argIndex];
  929. } else if (type[type.length - 1] === '*') {
  930. ret = HEAP[varArgStart+argIndex];
  931. } else {
  932. throw new Error('Unknown formatString argument type: ' + type);
  933. }
  934. argIndex += Runtime.getNativeFieldSize(type);
  935. return Number(ret);
  936. };
  937. } else {
  938. var args = arguments;
  939. getNextArg = function() {
  940. return Number(args[2 + argIndex++]);
  941. };
  942. }
  943.  
  944. var ret = [];
  945. var curr, next, currArg;
  946. while(1) {
  947. var startTextIndex = textIndex;
  948. curr = HEAP[textIndex];
  949. if (curr === 0) break;
  950. next = HEAP[textIndex+1];
  951. if (curr == '%'.charCodeAt(0)) {
  952. // Handle flags.
  953. var flagAlwaysSigned = false;
  954. var flagLeftAlign = false;
  955. var flagAlternative = false;
  956. var flagZeroPad = false;
  957. flagsLoop: while (1) {
  958. switch (next) {
  959. case '+'.charCodeAt(0):
  960. flagAlwaysSigned = true;
  961. break;
  962. case '-'.charCodeAt(0):
  963. flagLeftAlign = true;
  964. break;
  965. case '#'.charCodeAt(0):
  966. flagAlternative = true;
  967. break;
  968. case '0'.charCodeAt(0):
  969. if (flagZeroPad) {
  970. break flagsLoop;
  971. } else {
  972. flagZeroPad = true;
  973. break;
  974. }
  975. default:
  976. break flagsLoop;
  977. }
  978. textIndex++;
  979. next = HEAP[textIndex+1];
  980. }
  981.  
  982. // Handle width.
  983. var width = 0;
  984. if (next == '*'.charCodeAt(0)) {
  985. width = getNextArg('i32');
  986. textIndex++;
  987. next = HEAP[textIndex+1];
  988. } else {
  989. while (next >= '0'.charCodeAt(0) && next <= '9'.charCodeAt(0)) {
  990. width = width * 10 + (next - '0'.charCodeAt(0));
  991. textIndex++;
  992. next = HEAP[textIndex+1];
  993. }
  994. }
  995.  
  996. // Handle precision.
  997. var precisionSet = false;
  998. if (next == '.'.charCodeAt(0)) {
  999. var precision = 0;
  1000. precisionSet = true;
  1001. textIndex++;
  1002. next = HEAP[textIndex+1];
  1003. if (next == '*'.charCodeAt(0)) {
  1004. precision = getNextArg('i32');
  1005. textIndex++;
  1006. } else {
  1007. while(1) {
  1008. var precisionChr = HEAP[textIndex+1];
  1009. if (precisionChr < '0'.charCodeAt(0) ||
  1010. precisionChr > '9'.charCodeAt(0)) break;
  1011. precision = precision * 10 + (precisionChr - '0'.charCodeAt(0));
  1012. textIndex++;
  1013. }
  1014. }
  1015. next = HEAP[textIndex+1];
  1016. } else {
  1017. var precision = 6; // Standard default.
  1018. }
  1019.  
  1020. // Handle integer sizes. WARNING: These assume a 32-bit architecture!
  1021. var argSize;
  1022. switch (String.fromCharCode(next)) {
  1023. case 'h':
  1024. var nextNext = HEAP[textIndex+2];
  1025. if (nextNext == 'h'.charCodeAt(0)) {
  1026. textIndex++;
  1027. argSize = 1; // char
  1028. } else {
  1029. argSize = 2; // short
  1030. }
  1031. break;
  1032. case 'l':
  1033. var nextNext = HEAP[textIndex+2];
  1034. if (nextNext == 'l'.charCodeAt(0)) {
  1035. textIndex++;
  1036. argSize = 8; // long long
  1037. } else {
  1038. argSize = 4; // long
  1039. }
  1040. break;
  1041. case 'L': // long long
  1042. case 'q': // int64_t
  1043. case 'j': // intmax_t
  1044. argSize = 8;
  1045. break;
  1046. case 'z': // size_t
  1047. case 't': // ptrdiff_t
  1048. case 'I': // signed ptrdiff_t or unsigned size_t
  1049. argSize = 4;
  1050. break;
  1051. default:
  1052. argSize = undefined;
  1053. }
  1054. if (argSize !== undefined) textIndex++;
  1055. next = HEAP[textIndex+1];
  1056.  
  1057. // Handle type specifier.
  1058. if (['d', 'i', 'u', 'o', 'x', 'X', 'p'].indexOf(String.fromCharCode(next)) != -1) {
  1059. // Integer.
  1060. var signed = next == 'd'.charCodeAt(0) || next == 'i'.charCodeAt(0);
  1061. argSize = argSize || 4;
  1062. var currArg = getNextArg('i' + (argSize * 8));
  1063. // Truncate to requested size.
  1064. if (argSize <= 4) {
  1065. var limit = Math.pow(256, argSize) - 1;
  1066. currArg = (signed ? reSign : unSign)(currArg & limit, argSize * 8);
  1067. }
  1068. // Format the number.
  1069. var currAbsArg = Math.abs(currArg);
  1070. var argText;
  1071. var prefix = '';
  1072. if (next == 'd'.charCodeAt(0) || next == 'i'.charCodeAt(0)) {
  1073. argText = currAbsArg.toString(10);
  1074. } else if (next == 'u'.charCodeAt(0)) {
  1075. argText = unSign(currArg, 8 * argSize).toString(10);
  1076. currArg = Math.abs(currArg);
  1077. } else if (next == 'o'.charCodeAt(0)) {
  1078. argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8);
  1079. } else if (next == 'x'.charCodeAt(0) || next == 'X'.charCodeAt(0)) {
  1080. prefix = flagAlternative ? '0x' : '';
  1081. if (currArg < 0) {
  1082. // Represent negative numbers in hex as 2's complement.
  1083. currArg = -currArg;
  1084. argText = (currAbsArg - 1).toString(16);
  1085. var buffer = [];
  1086. for (var i = 0; i < argText.length; i++) {
  1087. buffer.push((0xF - parseInt(argText[i], 16)).toString(16));
  1088. }
  1089. argText = buffer.join('');
  1090. while (argText.length < argSize * 2) argText = 'f' + argText;
  1091. } else {
  1092. argText = currAbsArg.toString(16);
  1093. }
  1094. if (next == 'X'.charCodeAt(0)) {
  1095. prefix = prefix.toUpperCase();
  1096. argText = argText.toUpperCase();
  1097. }
  1098. } else if (next == 'p'.charCodeAt(0)) {
  1099. if (currAbsArg === 0) {
  1100. argText = '(nil)';
  1101. } else {
  1102. prefix = '0x';
  1103. argText = currAbsArg.toString(16);
  1104. }
  1105. }
  1106. if (precisionSet) {
  1107. while (argText.length < precision) {
  1108. argText = '0' + argText;
  1109. }
  1110. }
  1111.  
  1112. // Add sign.
  1113. if (currArg < 0) {
  1114. prefix = '-' + prefix;
  1115. } else if (flagAlwaysSigned) {
  1116. prefix = '+' + prefix;
  1117. }
  1118.  
  1119. // Add padding.
  1120. while (prefix.length + argText.length < width) {
  1121. if (flagLeftAlign) {
  1122. argText += ' ';
  1123. } else {
  1124. if (flagZeroPad) {
  1125. argText = '0' + argText;
  1126. } else {
  1127. prefix = ' ' + prefix;
  1128. }
  1129. }
  1130. }
  1131.  
  1132. // Insert the result into the buffer.
  1133. argText = prefix + argText;
  1134. argText.split('').forEach(function(chr) {
  1135. ret.push(chr.charCodeAt(0));
  1136. });
  1137. } else if (['f', 'F', 'e', 'E', 'g', 'G'].indexOf(String.fromCharCode(next)) != -1) {
  1138. // Float.
  1139. var currArg = getNextArg(argSize === 4 ? 'float' : 'double');
  1140. var argText;
  1141.  
  1142. if (isNaN(currArg)) {
  1143. argText = 'nan';
  1144. flagZeroPad = false;
  1145. } else if (!isFinite(currArg)) {
  1146. argText = (currArg < 0 ? '-' : '') + 'inf';
  1147. flagZeroPad = false;
  1148. } else {
  1149. var isGeneral = false;
  1150. var effectivePrecision = Math.min(precision, 20);
  1151.  
  1152. // Convert g/G to f/F or e/E, as per:
  1153. // http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html
  1154. if (next == 'g'.charCodeAt(0) || next == 'G'.charCodeAt(0)) {
  1155. isGeneral = true;
  1156. precision = precision || 1;
  1157. var exponent = parseInt(currArg.toExponential(effectivePrecision).split('e')[1], 10);
  1158. if (precision > exponent && exponent >= -4) {
  1159. next = ((next == 'g'.charCodeAt(0)) ? 'f' : 'F').charCodeAt(0);
  1160. precision -= exponent + 1;
  1161. } else {
  1162. next = ((next == 'g'.charCodeAt(0)) ? 'e' : 'E').charCodeAt(0);
  1163. precision--;
  1164. }
  1165. effectivePrecision = Math.min(precision, 20);
  1166. }
  1167.  
  1168. if (next == 'e'.charCodeAt(0) || next == 'E'.charCodeAt(0)) {
  1169. argText = currArg.toExponential(effectivePrecision);
  1170. // Make sure the exponent has at least 2 digits.
  1171. if (/[eE][-+]\d$/.test(argText)) {
  1172. argText = argText.slice(0, -1) + '0' + argText.slice(-1);
  1173. }
  1174. } else if (next == 'f'.charCodeAt(0) || next == 'F'.charCodeAt(0)) {
  1175. argText = currArg.toFixed(effectivePrecision);
  1176. }
  1177.  
  1178. var parts = argText.split('e');
  1179. if (isGeneral && !flagAlternative) {
  1180. // Discard trailing zeros and periods.
  1181. while (parts[0].length > 1 && parts[0].indexOf('.') != -1 &&
  1182. (parts[0].slice(-1) == '0' || parts[0].slice(-1) == '.')) {
  1183. parts[0] = parts[0].slice(0, -1);
  1184. }
  1185. } else {
  1186. // Make sure we have a period in alternative mode.
  1187. if (flagAlternative && argText.indexOf('.') == -1) parts[0] += '.';
  1188. // Zero pad until required precision.
  1189. while (precision > effectivePrecision++) parts[0] += '0';
  1190. }
  1191. argText = parts[0] + (parts.length > 1 ? 'e' + parts[1] : '');
  1192.  
  1193. // Capitalize 'E' if needed.
  1194. if (next == 'E'.charCodeAt(0)) argText = argText.toUpperCase();
  1195.  
  1196. // Add sign.
  1197. if (flagAlwaysSigned && currArg >= 0) {
  1198. argText = '+' + argText;
  1199. }
  1200. }
  1201.  
  1202. // Add padding.
  1203. while (argText.length < width) {
  1204. if (flagLeftAlign) {
  1205. argText += ' ';
  1206. } else {
  1207. if (flagZeroPad && (argText[0] == '-' || argText[0] == '+')) {
  1208. argText = argText[0] + '0' + argText.slice(1);
  1209. } else {
  1210. argText = (flagZeroPad ? '0' : ' ') + argText;
  1211. }
  1212. }
  1213. }
  1214.  
  1215. // Adjust case.
  1216. if (next < 'a'.charCodeAt(0)) argText = argText.toUpperCase();
  1217.  
  1218. // Insert the result into the buffer.
  1219. argText.split('').forEach(function(chr) {
  1220. ret.push(chr.charCodeAt(0));
  1221. });
  1222. } else if (next == 's'.charCodeAt(0)) {
  1223. // String.
  1224. var arg = getNextArg('i8*');
  1225. var copiedString;
  1226. if (arg) {
  1227. copiedString = String_copy(arg);
  1228. if (precisionSet && copiedString.length > precision) {
  1229. copiedString = copiedString.slice(0, precision);
  1230. }
  1231. } else {
  1232. copiedString = intArrayFromString('(null)', true);
  1233. }
  1234. if (!flagLeftAlign) {
  1235. while (copiedString.length < width--) {
  1236. ret.push(' '.charCodeAt(0));
  1237. }
  1238. }
  1239. ret = ret.concat(copiedString);
  1240. if (flagLeftAlign) {
  1241. while (copiedString.length < width--) {
  1242. ret.push(' '.charCodeAt(0));
  1243. }
  1244. }
  1245. } else if (next == 'c'.charCodeAt(0)) {
  1246. // Character.
  1247. if (flagLeftAlign) ret.push(getNextArg('i8'));
  1248. while (--width > 0) {
  1249. ret.push(' '.charCodeAt(0));
  1250. }
  1251. if (!flagLeftAlign) ret.push(getNextArg('i8'));
  1252. } else if (next == 'n'.charCodeAt(0)) {
  1253. // Write the length written so far to the next parameter.
  1254. var ptr = getNextArg('i32*');
  1255. HEAP[ptr]=ret.length;
  1256. } else if (next == '%'.charCodeAt(0)) {
  1257. // Literal percent sign.
  1258. ret.push(curr);
  1259. } else {
  1260. // Unknown specifiers remain untouched.
  1261. for (var i = startTextIndex; i < textIndex + 2; i++) {
  1262. ret.push(HEAP[i]);
  1263. }
  1264. }
  1265. textIndex += 2;
  1266. // TODO: Support a/A (hex float) and m (last error) specifiers.
  1267. // TODO: Support %1${specifier} for arg selection.
  1268. } else {
  1269. ret.push(curr);
  1270. textIndex += 1;
  1271. }
  1272. }
  1273. return ret;
  1274. };var _fprintf=function _fprintf (stream, format/*, ... */) {
  1275. // int fprintf(FILE *restrict stream, const char *restrict format, ...);
  1276. // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
  1277. var args = Array.prototype.slice.call(arguments, 1);
  1278. args.unshift(false);
  1279. var result = __formatString.apply(null, args);
  1280. var buffer = allocate(result, 'i8', ALLOC_NORMAL);
  1281. var ret = _fwrite(buffer, 1, result.length, stream);
  1282. _free(buffer);
  1283. return ret;
  1284. };var _printf=function _printf (format/*, ... */) {
  1285. // int printf(const char *restrict format, ...);
  1286. // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
  1287. var args = Array.prototype.slice.call(arguments, 0);
  1288. args.unshift(HEAP[_stdout]);
  1289. return _fprintf.apply(null, args);
  1290. };
  1291.  
  1292. var _memset=function _memset (ptr, value, num) {
  1293. for (var $mspi$ = 0; $mspi$ < num; $mspi$++) {
  1294. HEAP[ptr+$mspi$]=value;;
  1295. }
  1296. };
  1297.  
  1298. var _malloc=function staticAlloc(size) { var ret = STATICTOP; assert(size > 0, "Trying to allocate 0"); STATICTOP += size;STATICTOP = Math.ceil((STATICTOP)/4)*4;; return ret; };
  1299.  
  1300. var _free=function _free (){};
  1301.  
  1302. function _f($x, $y) {
  1303. var __stackBase__ = STACKTOP; STACKTOP += 24; assert(STACKTOP < STACK_MAX); _memset(__stackBase__, 0, 24);
  1304. var __label__;
  1305.  
  1306. var $1=__stackBase__;
  1307. var $2=__stackBase__+8;
  1308. var $3=__stackBase__+12;
  1309. var $tmp=__stackBase__+16;
  1310. HEAP[$2]=$x;
  1311. HEAP[$3]=$y;
  1312. var $4=HEAP[$2];
  1313. var $5=(($tmp)&4294967295);
  1314. HEAP[$5]=$4;
  1315. var $6=HEAP[$3];
  1316. var $7=(($tmp+4)&4294967295);
  1317. HEAP[$7]=$6;
  1318. var $8=$1;
  1319. var $9=$tmp;
  1320. _llvm_memcpy_p0i8_p0i8_i64($8, $9, 8, 4, 0);
  1321. var $10=$1;
  1322. var $11=HEAP[$10];
  1323. STACKTOP = __stackBase__;
  1324. return $11;
  1325. }
  1326.  
  1327.  
  1328. function _main() {
  1329. var __stackBase__ = STACKTOP; STACKTOP += 12; assert(STACKTOP < STACK_MAX); _memset(__stackBase__, 0, 12);
  1330. var __label__;
  1331.  
  1332. var $1=__stackBase__;
  1333. var $d=__stackBase__+4;
  1334. HEAP[$1]=0;
  1335. var $2=_f(5, 6);
  1336. var $3=$d;
  1337. HEAP[$3]=$2;
  1338. var $4=(($d)&4294967295);
  1339. var $5=HEAP[$4];
  1340. var $6=(($d+4)&4294967295);
  1341. var $7=HEAP[$6];
  1342. var $8=_printf(((__str)&4294967295), $5, $7);
  1343. var $9=HEAP[$1];
  1344. STACKTOP = __stackBase__;
  1345. return $9;
  1346. }
  1347. Module["_main"] = _main;
  1348. var FUNCTION_TABLE = [0,0];
  1349.  
  1350. // === Auto-generated postamble setup entry stuff ===
  1351.  
  1352. Module.callMain = function callMain(args) {
  1353. var argc = args.length+1;
  1354. function pad() {
  1355. for (var i = 0; i < 4-1; i++) {
  1356. argv.push(0);
  1357. }
  1358. }
  1359. var argv = [allocate(intArrayFromString("/bin/this.program"), 'i8', ALLOC_STATIC) ];
  1360. pad();
  1361. for (var i = 0; i < argc-1; i = i + 1) {
  1362. argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_STATIC));
  1363. pad();
  1364. }
  1365. argv.push(0);
  1366. argv = allocate(argv, 'i32', ALLOC_STATIC);
  1367.  
  1368. return _main(argc, argv, 0);
  1369. }
  1370.  
  1371. function run(args) {
  1372. args = args || Module['arguments'];
  1373.  
  1374.  
  1375. __str=allocate([37,100,32,37,100,10,0] /* %d %d\0A\00 */, "i8", ALLOC_STATIC);
  1376. FS.init();
  1377.  
  1378.  
  1379. __globalConstructor__();
  1380.  
  1381. var ret = null;
  1382. if (Module['_main']) {
  1383. ret = Module.callMain(args);
  1384. __shutdownRuntime__();
  1385. }
  1386. return ret;
  1387. }
  1388. Module['run'] = run;
  1389.  
  1390. // {{PRE_RUN_ADDITIONS}}
  1391.  
  1392.  
  1393. if (!Module['noInitialRun']) {
  1394. run();
  1395. }
  1396.  
  1397. // {{POST_RUN_ADDITIONS}}
  1398.  
  1399.  
  1400.  
  1401.  
  1402.  
  1403. // {{MODULE_ADDITIONS}}
  1404.  
  1405. /*
  1406. return Module;
  1407. }).call(this, {}, arguments); // Replace parameters as needed
  1408. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement