1var EXPECTED_OUTPUT = 2 '123456789\n' + 3 '213456789\n' + 4 '231456789\n' + 5 '321456789\n' + 6 '312456789\n' + 7 '132456789\n' + 8 '234156789\n' + 9 '324156789\n' + 10 '342156789\n' + 11 '432156789\n' + 12 '423156789\n' + 13 '243156789\n' + 14 '341256789\n' + 15 '431256789\n' + 16 '413256789\n' + 17 '143256789\n' + 18 '134256789\n' + 19 '314256789\n' + 20 '412356789\n' + 21 '142356789\n' + 22 '124356789\n' + 23 '214356789\n' + 24 '241356789\n' + 25 '421356789\n' + 26 '234516789\n' + 27 '324516789\n' + 28 '342516789\n' + 29 '432516789\n' + 30 '423516789\n' + 31 '243516789\n' + 32 'Pfannkuchen(9) = 30.\n'; 33var Module = { 34 arguments: [1], 35 print: function(x) {Module.printBuffer += x + '\n';}, 36 preRun: [function() {Module.printBuffer = ''}], 37 postRun: [function() { 38 assertEquals(EXPECTED_OUTPUT, Module.printBuffer); 39 }], 40}; 41// The Module object: Our interface to the outside world. We import 42// and export values on it, and do the work to get that through 43// closure compiler if necessary. There are various ways Module can be used: 44// 1. Not defined. We create it here 45// 2. A function parameter, function(Module) { ..generated code.. } 46// 3. pre-run appended it, var Module = {}; ..generated code.. 47// 4. External script tag defines var Module. 48// We need to do an eval in order to handle the closure compiler 49// case, where this code here is minified but Module was defined 50// elsewhere (e.g. case 4 above). We also need to check if Module 51// already exists (e.g. case 3 above). 52// Note that if you want to run closure, and also to use Module 53// after the generated code, you will need to define var Module = {}; 54// before the code. Then that object will be used in the code, and you 55// can continue to use Module afterwards as well. 56var Module; 57if (!Module) Module = (typeof Module !== 'undefined' ? Module : null) || {}; 58 59// Sometimes an existing Module object exists with properties 60// meant to overwrite the default module functionality. Here 61// we collect those properties and reapply _after_ we configure 62// the current environment's defaults to avoid having to be so 63// defensive during initialization. 64var moduleOverrides = {}; 65for (var key in Module) { 66 if (Module.hasOwnProperty(key)) { 67 moduleOverrides[key] = Module[key]; 68 } 69} 70 71// The environment setup code below is customized to use Module. 72// *** Environment setup code *** 73var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function'; 74var ENVIRONMENT_IS_WEB = typeof window === 'object'; 75var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function'; 76var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; 77 78if (ENVIRONMENT_IS_NODE) { 79 // Expose functionality in the same simple way that the shells work 80 // Note that we pollute the global namespace here, otherwise we break in node 81 if (!Module['print']) Module['print'] = function print(x) { 82 process['stdout'].write(x + '\n'); 83 }; 84 if (!Module['printErr']) Module['printErr'] = function printErr(x) { 85 process['stderr'].write(x + '\n'); 86 }; 87 88 var nodeFS = require('fs'); 89 var nodePath = require('path'); 90 91 Module['read'] = function read(filename, binary) { 92 filename = nodePath['normalize'](filename); 93 var ret = nodeFS['readFileSync'](filename); 94 // The path is absolute if the normalized version is the same as the resolved. 95 if (!ret && filename != nodePath['resolve'](filename)) { 96 filename = path.join(__dirname, '..', 'src', filename); 97 ret = nodeFS['readFileSync'](filename); 98 } 99 if (ret && !binary) ret = ret.toString(); 100 return ret; 101 }; 102 103 Module['readBinary'] = function readBinary(filename) { return Module['read'](filename, true) }; 104 105 Module['load'] = function load(f) { 106 globalEval(read(f)); 107 }; 108 109 Module['arguments'] = process['argv'].slice(2); 110 111 module['exports'] = Module; 112} 113else if (ENVIRONMENT_IS_SHELL) { 114 if (!Module['print']) Module['print'] = print; 115 if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm 116 117 if (typeof read != 'undefined') { 118 Module['read'] = read; 119 } else { 120 Module['read'] = function read() { throw 'no read() available (jsc?)' }; 121 } 122 123 Module['readBinary'] = function readBinary(f) { 124 return read(f, 'binary'); 125 }; 126 127 if (typeof scriptArgs != 'undefined') { 128 Module['arguments'] = scriptArgs; 129 } else if (typeof arguments != 'undefined') { 130 Module['arguments'] = arguments; 131 } 132 133 this['Module'] = Module; 134 135 eval("if (typeof gc === 'function' && gc.toString().indexOf('[native code]') > 0) var gc = undefined"); // wipe out the SpiderMonkey shell 'gc' function, which can confuse closure (uses it as a minified name, and it is then initted to a non-falsey value unexpectedly) 136} 137else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { 138 Module['read'] = function read(url) { 139 var xhr = new XMLHttpRequest(); 140 xhr.open('GET', url, false); 141 xhr.send(null); 142 return xhr.responseText; 143 }; 144 145 if (typeof arguments != 'undefined') { 146 Module['arguments'] = arguments; 147 } 148 149 if (typeof console !== 'undefined') { 150 if (!Module['print']) Module['print'] = function print(x) { 151 console.log(x); 152 }; 153 if (!Module['printErr']) Module['printErr'] = function printErr(x) { 154 console.log(x); 155 }; 156 } else { 157 // Probably a worker, and without console.log. We can do very little here... 158 var TRY_USE_DUMP = false; 159 if (!Module['print']) Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) { 160 dump(x); 161 }) : (function(x) { 162 // self.postMessage(x); // enable this if you want stdout to be sent as messages 163 })); 164 } 165 166 if (ENVIRONMENT_IS_WEB) { 167 window['Module'] = Module; 168 } else { 169 Module['load'] = importScripts; 170 } 171} 172else { 173 // Unreachable because SHELL is dependant on the others 174 throw 'Unknown runtime environment. Where are we?'; 175} 176 177function globalEval(x) { 178 eval.call(null, x); 179} 180if (!Module['load'] == 'undefined' && Module['read']) { 181 Module['load'] = function load(f) { 182 globalEval(Module['read'](f)); 183 }; 184} 185if (!Module['print']) { 186 Module['print'] = function(){}; 187} 188if (!Module['printErr']) { 189 Module['printErr'] = Module['print']; 190} 191if (!Module['arguments']) { 192 Module['arguments'] = []; 193} 194// *** Environment setup code *** 195 196// Closure helpers 197Module.print = Module['print']; 198Module.printErr = Module['printErr']; 199 200// Callbacks 201Module['preRun'] = []; 202Module['postRun'] = []; 203 204// Merge back in the overrides 205for (var key in moduleOverrides) { 206 if (moduleOverrides.hasOwnProperty(key)) { 207 Module[key] = moduleOverrides[key]; 208 } 209} 210 211 212 213// === Auto-generated preamble library stuff === 214 215//======================================== 216// Runtime code shared with compiler 217//======================================== 218 219var Runtime = { 220 stackSave: function () { 221 return STACKTOP; 222 }, 223 stackRestore: function (stackTop) { 224 STACKTOP = stackTop; 225 }, 226 forceAlign: function (target, quantum) { 227 quantum = quantum || 4; 228 if (quantum == 1) return target; 229 if (isNumber(target) && isNumber(quantum)) { 230 return Math.ceil(target/quantum)*quantum; 231 } else if (isNumber(quantum) && isPowerOfTwo(quantum)) { 232 return '(((' +target + ')+' + (quantum-1) + ')&' + -quantum + ')'; 233 } 234 return 'Math.ceil((' + target + ')/' + quantum + ')*' + quantum; 235 }, 236 isNumberType: function (type) { 237 return type in Runtime.INT_TYPES || type in Runtime.FLOAT_TYPES; 238 }, 239 isPointerType: function isPointerType(type) { 240 return type[type.length-1] == '*'; 241}, 242 isStructType: function isStructType(type) { 243 if (isPointerType(type)) return false; 244 if (isArrayType(type)) return true; 245 if (/<?\{ ?[^}]* ?\}>?/.test(type)) return true; // { i32, i8 } etc. - anonymous struct types 246 // See comment in isStructPointerType() 247 return type[0] == '%'; 248}, 249 INT_TYPES: {"i1":0,"i8":0,"i16":0,"i32":0,"i64":0}, 250 FLOAT_TYPES: {"float":0,"double":0}, 251 or64: function (x, y) { 252 var l = (x | 0) | (y | 0); 253 var h = (Math.round(x / 4294967296) | Math.round(y / 4294967296)) * 4294967296; 254 return l + h; 255 }, 256 and64: function (x, y) { 257 var l = (x | 0) & (y | 0); 258 var h = (Math.round(x / 4294967296) & Math.round(y / 4294967296)) * 4294967296; 259 return l + h; 260 }, 261 xor64: function (x, y) { 262 var l = (x | 0) ^ (y | 0); 263 var h = (Math.round(x / 4294967296) ^ Math.round(y / 4294967296)) * 4294967296; 264 return l + h; 265 }, 266 getNativeTypeSize: function (type) { 267 switch (type) { 268 case 'i1': case 'i8': return 1; 269 case 'i16': return 2; 270 case 'i32': return 4; 271 case 'i64': return 8; 272 case 'float': return 4; 273 case 'double': return 8; 274 default: { 275 if (type[type.length-1] === '*') { 276 return Runtime.QUANTUM_SIZE; // A pointer 277 } else if (type[0] === 'i') { 278 var bits = parseInt(type.substr(1)); 279 assert(bits % 8 === 0); 280 return bits/8; 281 } else { 282 return 0; 283 } 284 } 285 } 286 }, 287 getNativeFieldSize: function (type) { 288 return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE); 289 }, 290 dedup: function dedup(items, ident) { 291 var seen = {}; 292 if (ident) { 293 return items.filter(function(item) { 294 if (seen[item[ident]]) return false; 295 seen[item[ident]] = true; 296 return true; 297 }); 298 } else { 299 return items.filter(function(item) { 300 if (seen[item]) return false; 301 seen[item] = true; 302 return true; 303 }); 304 } 305}, 306 set: function set() { 307 var args = typeof arguments[0] === 'object' ? arguments[0] : arguments; 308 var ret = {}; 309 for (var i = 0; i < args.length; i++) { 310 ret[args[i]] = 0; 311 } 312 return ret; 313}, 314 STACK_ALIGN: 8, 315 getAlignSize: function (type, size, vararg) { 316 // we align i64s and doubles on 64-bit boundaries, unlike x86 317 if (!vararg && (type == 'i64' || type == 'double')) return 8; 318 if (!type) return Math.min(size, 8); // align structures internally to 64 bits 319 return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE); 320 }, 321 calculateStructAlignment: function calculateStructAlignment(type) { 322 type.flatSize = 0; 323 type.alignSize = 0; 324 var diffs = []; 325 var prev = -1; 326 var index = 0; 327 type.flatIndexes = type.fields.map(function(field) { 328 index++; 329 var size, alignSize; 330 if (Runtime.isNumberType(field) || Runtime.isPointerType(field)) { 331 size = Runtime.getNativeTypeSize(field); // pack char; char; in structs, also char[X]s. 332 alignSize = Runtime.getAlignSize(field, size); 333 } else if (Runtime.isStructType(field)) { 334 if (field[1] === '0') { 335 // this is [0 x something]. When inside another structure like here, it must be at the end, 336 // and it adds no size 337 // XXX this happens in java-nbody for example... assert(index === type.fields.length, 'zero-length in the middle!'); 338 size = 0; 339 if (Types.types[field]) { 340 alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize); 341 } else { 342 alignSize = type.alignSize || QUANTUM_SIZE; 343 } 344 } else { 345 size = Types.types[field].flatSize; 346 alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize); 347 } 348 } else if (field[0] == 'b') { 349 // bN, large number field, like a [N x i8] 350 size = field.substr(1)|0; 351 alignSize = 1; 352 } else if (field[0] === '<') { 353 // vector type 354 size = alignSize = Types.types[field].flatSize; // fully aligned 355 } else if (field[0] === 'i') { 356 // illegal integer field, that could not be legalized because it is an internal structure field 357 // it is ok to have such fields, if we just use them as markers of field size and nothing more complex 358 size = alignSize = parseInt(field.substr(1))/8; 359 assert(size % 1 === 0, 'cannot handle non-byte-size field ' + field); 360 } else { 361 assert(false, 'invalid type for calculateStructAlignment'); 362 } 363 if (type.packed) alignSize = 1; 364 type.alignSize = Math.max(type.alignSize, alignSize); 365 var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory 366 type.flatSize = curr + size; 367 if (prev >= 0) { 368 diffs.push(curr-prev); 369 } 370 prev = curr; 371 return curr; 372 }); 373 if (type.name_ && type.name_[0] === '[') { 374 // arrays have 2 elements, so we get the proper difference. then we scale here. that way we avoid 375 // allocating a potentially huge array for [999999 x i8] etc. 376 type.flatSize = parseInt(type.name_.substr(1))*type.flatSize/2; 377 } 378 type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize); 379 if (diffs.length == 0) { 380 type.flatFactor = type.flatSize; 381 } else if (Runtime.dedup(diffs).length == 1) { 382 type.flatFactor = diffs[0]; 383 } 384 type.needsFlattening = (type.flatFactor != 1); 385 return type.flatIndexes; 386 }, 387 generateStructInfo: function (struct, typeName, offset) { 388 var type, alignment; 389 if (typeName) { 390 offset = offset || 0; 391 type = (typeof Types === 'undefined' ? Runtime.typeInfo : Types.types)[typeName]; 392 if (!type) return null; 393 if (type.fields.length != struct.length) { 394 printErr('Number of named fields must match the type for ' + typeName + ': possibly duplicate struct names. Cannot return structInfo'); 395 return null; 396 } 397 alignment = type.flatIndexes; 398 } else { 399 var type = { fields: struct.map(function(item) { return item[0] }) }; 400 alignment = Runtime.calculateStructAlignment(type); 401 } 402 var ret = { 403 __size__: type.flatSize 404 }; 405 if (typeName) { 406 struct.forEach(function(item, i) { 407 if (typeof item === 'string') { 408 ret[item] = alignment[i] + offset; 409 } else { 410 // embedded struct 411 var key; 412 for (var k in item) key = k; 413 ret[key] = Runtime.generateStructInfo(item[key], type.fields[i], alignment[i]); 414 } 415 }); 416 } else { 417 struct.forEach(function(item, i) { 418 ret[item[1]] = alignment[i]; 419 }); 420 } 421 return ret; 422 }, 423 dynCall: function (sig, ptr, args) { 424 if (args && args.length) { 425 if (!args.splice) args = Array.prototype.slice.call(args); 426 args.splice(0, 0, ptr); 427 return Module['dynCall_' + sig].apply(null, args); 428 } else { 429 return Module['dynCall_' + sig].call(null, ptr); 430 } 431 }, 432 functionPointers: [], 433 addFunction: function (func) { 434 for (var i = 0; i < Runtime.functionPointers.length; i++) { 435 if (!Runtime.functionPointers[i]) { 436 Runtime.functionPointers[i] = func; 437 return 2*(1 + i); 438 } 439 } 440 throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.'; 441 }, 442 removeFunction: function (index) { 443 Runtime.functionPointers[(index-2)/2] = null; 444 }, 445 getAsmConst: function (code, numArgs) { 446 // code is a constant string on the heap, so we can cache these 447 if (!Runtime.asmConstCache) Runtime.asmConstCache = {}; 448 var func = Runtime.asmConstCache[code]; 449 if (func) return func; 450 var args = []; 451 for (var i = 0; i < numArgs; i++) { 452 args.push(String.fromCharCode(36) + i); // $0, $1 etc 453 } 454 var source = Pointer_stringify(code); 455 if (source[0] === '"') { 456 // tolerate EM_ASM("..code..") even though EM_ASM(..code..) is correct 457 if (source.indexOf('"', 1) === source.length-1) { 458 source = source.substr(1, source.length-2); 459 } else { 460 // something invalid happened, e.g. EM_ASM("..code($0)..", input) 461 abort('invalid EM_ASM input |' + source + '|. Please use EM_ASM(..code..) (no quotes) or EM_ASM({ ..code($0).. }, input) (to input values)'); 462 } 463 } 464 try { 465 var evalled = eval('(function(' + args.join(',') + '){ ' + source + ' })'); // new Function does not allow upvars in node 466 } catch(e) { 467 Module.printErr('error in executing inline EM_ASM code: ' + e + ' on: \n\n' + source + '\n\nwith args |' + args + '| (make sure to use the right one out of EM_ASM, EM_ASM_ARGS, etc.)'); 468 throw e; 469 } 470 return Runtime.asmConstCache[code] = evalled; 471 }, 472 warnOnce: function (text) { 473 if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {}; 474 if (!Runtime.warnOnce.shown[text]) { 475 Runtime.warnOnce.shown[text] = 1; 476 Module.printErr(text); 477 } 478 }, 479 funcWrappers: {}, 480 getFuncWrapper: function (func, sig) { 481 assert(sig); 482 if (!Runtime.funcWrappers[func]) { 483 Runtime.funcWrappers[func] = function dynCall_wrapper() { 484 return Runtime.dynCall(sig, func, arguments); 485 }; 486 } 487 return Runtime.funcWrappers[func]; 488 }, 489 UTF8Processor: function () { 490 var buffer = []; 491 var needed = 0; 492 this.processCChar = function (code) { 493 code = code & 0xFF; 494 495 if (buffer.length == 0) { 496 if ((code & 0x80) == 0x00) { // 0xxxxxxx 497 return String.fromCharCode(code); 498 } 499 buffer.push(code); 500 if ((code & 0xE0) == 0xC0) { // 110xxxxx 501 needed = 1; 502 } else if ((code & 0xF0) == 0xE0) { // 1110xxxx 503 needed = 2; 504 } else { // 11110xxx 505 needed = 3; 506 } 507 return ''; 508 } 509 510 if (needed) { 511 buffer.push(code); 512 needed--; 513 if (needed > 0) return ''; 514 } 515 516 var c1 = buffer[0]; 517 var c2 = buffer[1]; 518 var c3 = buffer[2]; 519 var c4 = buffer[3]; 520 var ret; 521 if (buffer.length == 2) { 522 ret = String.fromCharCode(((c1 & 0x1F) << 6) | (c2 & 0x3F)); 523 } else if (buffer.length == 3) { 524 ret = String.fromCharCode(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)); 525 } else { 526 // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae 527 var codePoint = ((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) | 528 ((c3 & 0x3F) << 6) | (c4 & 0x3F); 529 ret = String.fromCharCode( 530 Math.floor((codePoint - 0x10000) / 0x400) + 0xD800, 531 (codePoint - 0x10000) % 0x400 + 0xDC00); 532 } 533 buffer.length = 0; 534 return ret; 535 } 536 this.processJSString = function processJSString(string) { 537 /* TODO: use TextEncoder when present, 538 var encoder = new TextEncoder(); 539 encoder['encoding'] = "utf-8"; 540 var utf8Array = encoder['encode'](aMsg.data); 541 */ 542 string = unescape(encodeURIComponent(string)); 543 var ret = []; 544 for (var i = 0; i < string.length; i++) { 545 ret.push(string.charCodeAt(i)); 546 } 547 return ret; 548 } 549 }, 550 getCompilerSetting: function (name) { 551 throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work'; 552 }, 553 stackAlloc: function (size) { var ret = STACKTOP;STACKTOP = (STACKTOP + size)|0;STACKTOP = (((STACKTOP)+7)&-8); return ret; }, 554 staticAlloc: function (size) { var ret = STATICTOP;STATICTOP = (STATICTOP + size)|0;STATICTOP = (((STATICTOP)+7)&-8); return ret; }, 555 dynamicAlloc: function (size) { var ret = DYNAMICTOP;DYNAMICTOP = (DYNAMICTOP + size)|0;DYNAMICTOP = (((DYNAMICTOP)+7)&-8); if (DYNAMICTOP >= TOTAL_MEMORY) enlargeMemory();; return ret; }, 556 alignMemory: function (size,quantum) { var ret = size = Math.ceil((size)/(quantum ? quantum : 8))*(quantum ? quantum : 8); return ret; }, 557 makeBigInt: function (low,high,unsigned) { var ret = (unsigned ? ((+((low>>>0)))+((+((high>>>0)))*(+4294967296))) : ((+((low>>>0)))+((+((high|0)))*(+4294967296)))); return ret; }, 558 GLOBAL_BASE: 8, 559 QUANTUM_SIZE: 4, 560 __dummy__: 0 561} 562 563 564Module['Runtime'] = Runtime; 565 566 567 568 569 570 571 572 573 574//======================================== 575// Runtime essentials 576//======================================== 577 578var __THREW__ = 0; // Used in checking for thrown exceptions. 579 580var ABORT = false; // whether we are quitting the application. no code should run after this. set in exit() and abort() 581var EXITSTATUS = 0; 582 583var undef = 0; 584// tempInt is used for 32-bit signed values or smaller. tempBigInt is used 585// for 32-bit unsigned values or more than 32 bits. TODO: audit all uses of tempInt 586var tempValue, tempInt, tempBigInt, tempInt2, tempBigInt2, tempPair, tempBigIntI, tempBigIntR, tempBigIntS, tempBigIntP, tempBigIntD, tempDouble, tempFloat; 587var tempI64, tempI64b; 588var tempRet0, tempRet1, tempRet2, tempRet3, tempRet4, tempRet5, tempRet6, tempRet7, tempRet8, tempRet9; 589 590function assert(condition, text) { 591 if (!condition) { 592 abort('Assertion failed: ' + text); 593 } 594} 595 596var globalScope = this; 597 598// C calling interface. A convenient way to call C functions (in C files, or 599// defined with extern "C"). 600// 601// Note: LLVM optimizations can inline and remove functions, after which you will not be 602// able to call them. Closure can also do so. To avoid that, add your function to 603// the exports using something like 604// 605// -s EXPORTED_FUNCTIONS='["_main", "_myfunc"]' 606// 607// @param ident The name of the C function (note that C++ functions will be name-mangled - use extern "C") 608// @param returnType The return type of the function, one of the JS types 'number', 'string' or 'array' (use 'number' for any C pointer, and 609// 'array' for JavaScript arrays and typed arrays; note that arrays are 8-bit). 610// @param argTypes An array of the types of arguments for the function (if there are no arguments, this can be ommitted). Types are as in returnType, 611// except that 'array' is not possible (there is no way for us to know the length of the array) 612// @param args An array of the arguments to the function, as native JS values (as in returnType) 613// Note that string arguments will be stored on the stack (the JS string will become a C string on the stack). 614// @return The return value, as a native JS value (as in returnType) 615function ccall(ident, returnType, argTypes, args) { 616 return ccallFunc(getCFunc(ident), returnType, argTypes, args); 617} 618Module["ccall"] = ccall; 619 620// Returns the C function with a specified identifier (for C++, you need to do manual name mangling) 621function getCFunc(ident) { 622 try { 623 var func = Module['_' + ident]; // closure exported function 624 if (!func) func = eval('_' + ident); // explicit lookup 625 } catch(e) { 626 } 627 assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)'); 628 return func; 629} 630 631// Internal function that does a C call using a function, not an identifier 632function ccallFunc(func, returnType, argTypes, args) { 633 var stack = 0; 634 function toC(value, type) { 635 if (type == 'string') { 636 if (value === null || value === undefined || value === 0) return 0; // null string 637 value = intArrayFromString(value); 638 type = 'array'; 639 } 640 if (type == 'array') { 641 if (!stack) stack = Runtime.stackSave(); 642 var ret = Runtime.stackAlloc(value.length); 643 writeArrayToMemory(value, ret); 644 return ret; 645 } 646 return value; 647 } 648 function fromC(value, type) { 649 if (type == 'string') { 650 return Pointer_stringify(value); 651 } 652 assert(type != 'array'); 653 return value; 654 } 655 var i = 0; 656 var cArgs = args ? args.map(function(arg) { 657 return toC(arg, argTypes[i++]); 658 }) : []; 659 var ret = fromC(func.apply(null, cArgs), returnType); 660 if (stack) Runtime.stackRestore(stack); 661 return ret; 662} 663 664// Returns a native JS wrapper for a C function. This is similar to ccall, but 665// returns a function you can call repeatedly in a normal way. For example: 666// 667// var my_function = cwrap('my_c_function', 'number', ['number', 'number']); 668// alert(my_function(5, 22)); 669// alert(my_function(99, 12)); 670// 671function cwrap(ident, returnType, argTypes) { 672 var func = getCFunc(ident); 673 return function() { 674 return ccallFunc(func, returnType, argTypes, Array.prototype.slice.call(arguments)); 675 } 676} 677Module["cwrap"] = cwrap; 678 679// Sets a value in memory in a dynamic way at run-time. Uses the 680// type data. This is the same as makeSetValue, except that 681// makeSetValue is done at compile-time and generates the needed 682// code then, whereas this function picks the right code at 683// run-time. 684// Note that setValue and getValue only do *aligned* writes and reads! 685// Note that ccall uses JS types as for defining types, while setValue and 686// getValue need LLVM types ('i8', 'i32') - this is a lower-level operation 687function setValue(ptr, value, type, noSafe) { 688 type = type || 'i8'; 689 if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit 690 switch(type) { 691 case 'i1': HEAP8[(ptr)]=value; break; 692 case 'i8': HEAP8[(ptr)]=value; break; 693 case 'i16': HEAP16[((ptr)>>1)]=value; break; 694 case 'i32': HEAP32[((ptr)>>2)]=value; break; 695 case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= (+1) ? (tempDouble > (+0) ? ((Math_min((+(Math_floor((tempDouble)/(+4294967296)))), (+4294967295)))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/(+4294967296))))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break; 696 case 'float': HEAPF32[((ptr)>>2)]=value; break; 697 case 'double': HEAPF64[((ptr)>>3)]=value; break; 698 default: abort('invalid type for setValue: ' + type); 699 } 700} 701Module['setValue'] = setValue; 702 703// Parallel to setValue. 704function getValue(ptr, type, noSafe) { 705 type = type || 'i8'; 706 if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit 707 switch(type) { 708 case 'i1': return HEAP8[(ptr)]; 709 case 'i8': return HEAP8[(ptr)]; 710 case 'i16': return HEAP16[((ptr)>>1)]; 711 case 'i32': return HEAP32[((ptr)>>2)]; 712 case 'i64': return HEAP32[((ptr)>>2)]; 713 case 'float': return HEAPF32[((ptr)>>2)]; 714 case 'double': return HEAPF64[((ptr)>>3)]; 715 default: abort('invalid type for setValue: ' + type); 716 } 717 return null; 718} 719Module['getValue'] = getValue; 720 721var ALLOC_NORMAL = 0; // Tries to use _malloc() 722var ALLOC_STACK = 1; // Lives for the duration of the current function call 723var ALLOC_STATIC = 2; // Cannot be freed 724var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk 725var ALLOC_NONE = 4; // Do not allocate 726Module['ALLOC_NORMAL'] = ALLOC_NORMAL; 727Module['ALLOC_STACK'] = ALLOC_STACK; 728Module['ALLOC_STATIC'] = ALLOC_STATIC; 729Module['ALLOC_DYNAMIC'] = ALLOC_DYNAMIC; 730Module['ALLOC_NONE'] = ALLOC_NONE; 731 732// allocate(): This is for internal use. You can use it yourself as well, but the interface 733// is a little tricky (see docs right below). The reason is that it is optimized 734// for multiple syntaxes to save space in generated code. So you should 735// normally not use allocate(), and instead allocate memory using _malloc(), 736// initialize it with setValue(), and so forth. 737// @slab: An array of data, or a number. If a number, then the size of the block to allocate, 738// in *bytes* (note that this is sometimes confusing: the next parameter does not 739// affect this!) 740// @types: Either an array of types, one for each byte (or 0 if no type at that position), 741// or a single type which is used for the entire block. This only matters if there 742// is initial data - if @slab is a number, then this does not matter at all and is 743// ignored. 744// @allocator: How to allocate memory, see ALLOC_* 745function allocate(slab, types, allocator, ptr) { 746 var zeroinit, size; 747 if (typeof slab === 'number') { 748 zeroinit = true; 749 size = slab; 750 } else { 751 zeroinit = false; 752 size = slab.length; 753 } 754 755 var singleType = typeof types === 'string' ? types : null; 756 757 var ret; 758 if (allocator == ALLOC_NONE) { 759 ret = ptr; 760 } else { 761 ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc, Runtime.dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length)); 762 } 763 764 if (zeroinit) { 765 var ptr = ret, stop; 766 assert((ret & 3) == 0); 767 stop = ret + (size & ~3); 768 for (; ptr < stop; ptr += 4) { 769 HEAP32[((ptr)>>2)]=0; 770 } 771 stop = ret + size; 772 while (ptr < stop) { 773 HEAP8[((ptr++)|0)]=0; 774 } 775 return ret; 776 } 777 778 if (singleType === 'i8') { 779 if (slab.subarray || slab.slice) { 780 HEAPU8.set(slab, ret); 781 } else { 782 HEAPU8.set(new Uint8Array(slab), ret); 783 } 784 return ret; 785 } 786 787 var i = 0, type, typeSize, previousType; 788 while (i < size) { 789 var curr = slab[i]; 790 791 if (typeof curr === 'function') { 792 curr = Runtime.getFunctionIndex(curr); 793 } 794 795 type = singleType || types[i]; 796 if (type === 0) { 797 i++; 798 continue; 799 } 800 801 if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later 802 803 setValue(ret+i, curr, type); 804 805 // no need to look up size unless type changes, so cache it 806 if (previousType !== type) { 807 typeSize = Runtime.getNativeTypeSize(type); 808 previousType = type; 809 } 810 i += typeSize; 811 } 812 813 return ret; 814} 815Module['allocate'] = allocate; 816 817function Pointer_stringify(ptr, /* optional */ length) { 818 // TODO: use TextDecoder 819 // Find the length, and check for UTF while doing so 820 var hasUtf = false; 821 var t; 822 var i = 0; 823 while (1) { 824 t = HEAPU8[(((ptr)+(i))|0)]; 825 if (t >= 128) hasUtf = true; 826 else if (t == 0 && !length) break; 827 i++; 828 if (length && i == length) break; 829 } 830 if (!length) length = i; 831 832 var ret = ''; 833 834 if (!hasUtf) { 835 var MAX_CHUNK = 1024; // split up into chunks, because .apply on a huge string can overflow the stack 836 var curr; 837 while (length > 0) { 838 curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK))); 839 ret = ret ? ret + curr : curr; 840 ptr += MAX_CHUNK; 841 length -= MAX_CHUNK; 842 } 843 return ret; 844 } 845 846 var utf8 = new Runtime.UTF8Processor(); 847 for (i = 0; i < length; i++) { 848 t = HEAPU8[(((ptr)+(i))|0)]; 849 ret += utf8.processCChar(t); 850 } 851 return ret; 852} 853Module['Pointer_stringify'] = Pointer_stringify; 854 855// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns 856// a copy of that string as a Javascript String object. 857function UTF16ToString(ptr) { 858 var i = 0; 859 860 var str = ''; 861 while (1) { 862 var codeUnit = HEAP16[(((ptr)+(i*2))>>1)]; 863 if (codeUnit == 0) 864 return str; 865 ++i; 866 // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through. 867 str += String.fromCharCode(codeUnit); 868 } 869} 870Module['UTF16ToString'] = UTF16ToString; 871 872// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', 873// null-terminated and encoded in UTF16LE form. The copy will require at most (str.length*2+1)*2 bytes of space in the HEAP. 874function stringToUTF16(str, outPtr) { 875 for(var i = 0; i < str.length; ++i) { 876 // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP. 877 var codeUnit = str.charCodeAt(i); // possibly a lead surrogate 878 HEAP16[(((outPtr)+(i*2))>>1)]=codeUnit; 879 } 880 // Null-terminate the pointer to the HEAP. 881 HEAP16[(((outPtr)+(str.length*2))>>1)]=0; 882} 883Module['stringToUTF16'] = stringToUTF16; 884 885// Given a pointer 'ptr' to a null-terminated UTF32LE-encoded string in the emscripten HEAP, returns 886// a copy of that string as a Javascript String object. 887function UTF32ToString(ptr) { 888 var i = 0; 889 890 var str = ''; 891 while (1) { 892 var utf32 = HEAP32[(((ptr)+(i*4))>>2)]; 893 if (utf32 == 0) 894 return str; 895 ++i; 896 // 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. 897 if (utf32 >= 0x10000) { 898 var ch = utf32 - 0x10000; 899 str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); 900 } else { 901 str += String.fromCharCode(utf32); 902 } 903 } 904} 905Module['UTF32ToString'] = UTF32ToString; 906 907// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', 908// null-terminated and encoded in UTF32LE form. The copy will require at most (str.length+1)*4 bytes of space in the HEAP, 909// but can use less, since str.length does not return the number of characters in the string, but the number of UTF-16 code units in the string. 910function stringToUTF32(str, outPtr) { 911 var iChar = 0; 912 for(var iCodeUnit = 0; iCodeUnit < str.length; ++iCodeUnit) { 913 // 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. 914 var codeUnit = str.charCodeAt(iCodeUnit); // possibly a lead surrogate 915 if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) { 916 var trailSurrogate = str.charCodeAt(++iCodeUnit); 917 codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF); 918 } 919 HEAP32[(((outPtr)+(iChar*4))>>2)]=codeUnit; 920 ++iChar; 921 } 922 // Null-terminate the pointer to the HEAP. 923 HEAP32[(((outPtr)+(iChar*4))>>2)]=0; 924} 925Module['stringToUTF32'] = stringToUTF32; 926 927function demangle(func) { 928 var i = 3; 929 // params, etc. 930 var basicTypes = { 931 'v': 'void', 932 'b': 'bool', 933 'c': 'char', 934 's': 'short', 935 'i': 'int', 936 'l': 'long', 937 'f': 'float', 938 'd': 'double', 939 'w': 'wchar_t', 940 'a': 'signed char', 941 'h': 'unsigned char', 942 't': 'unsigned short', 943 'j': 'unsigned int', 944 'm': 'unsigned long', 945 'x': 'long long', 946 'y': 'unsigned long long', 947 'z': '...' 948 }; 949 var subs = []; 950 var first = true; 951 function dump(x) { 952 //return; 953 if (x) Module.print(x); 954 Module.print(func); 955 var pre = ''; 956 for (var a = 0; a < i; a++) pre += ' '; 957 Module.print (pre + '^'); 958 } 959 function parseNested() { 960 i++; 961 if (func[i] === 'K') i++; // ignore const 962 var parts = []; 963 while (func[i] !== 'E') { 964 if (func[i] === 'S') { // substitution 965 i++; 966 var next = func.indexOf('_', i); 967 var num = func.substring(i, next) || 0; 968 parts.push(subs[num] || '?'); 969 i = next+1; 970 continue; 971 } 972 if (func[i] === 'C') { // constructor 973 parts.push(parts[parts.length-1]); 974 i += 2; 975 continue; 976 } 977 var size = parseInt(func.substr(i)); 978 var pre = size.toString().length; 979 if (!size || !pre) { i--; break; } // counter i++ below us 980 var curr = func.substr(i + pre, size); 981 parts.push(curr); 982 subs.push(curr); 983 i += pre + size; 984 } 985 i++; // skip E 986 return parts; 987 } 988 function parse(rawList, limit, allowVoid) { // main parser 989 limit = limit || Infinity; 990 var ret = '', list = []; 991 function flushList() { 992 return '(' + list.join(', ') + ')'; 993 } 994 var name; 995 if (func[i] === 'N') { 996 // namespaced N-E 997 name = parseNested().join('::'); 998 limit--; 999 if (limit === 0) return rawList ? [name] : name; 1000 } else { 1001 // not namespaced 1002 if (func[i] === 'K' || (first && func[i] === 'L')) i++; // ignore const and first 'L' 1003 var size = parseInt(func.substr(i)); 1004 if (size) { 1005 var pre = size.toString().length; 1006 name = func.substr(i + pre, size); 1007 i += pre + size; 1008 } 1009 } 1010 first = false; 1011 if (func[i] === 'I') { 1012 i++; 1013 var iList = parse(true); 1014 var iRet = parse(true, 1, true); 1015 ret += iRet[0] + ' ' + name + '<' + iList.join(', ') + '>'; 1016 } else { 1017 ret = name; 1018 } 1019 paramLoop: while (i < func.length && limit-- > 0) { 1020 //dump('paramLoop'); 1021 var c = func[i++]; 1022 if (c in basicTypes) { 1023 list.push(basicTypes[c]); 1024 } else { 1025 switch (c) { 1026 case 'P': list.push(parse(true, 1, true)[0] + '*'); break; // pointer 1027 case 'R': list.push(parse(true, 1, true)[0] + '&'); break; // reference 1028 case 'L': { // literal 1029 i++; // skip basic type 1030 var end = func.indexOf('E', i); 1031 var size = end - i; 1032 list.push(func.substr(i, size)); 1033 i += size + 2; // size + 'EE' 1034 break; 1035 } 1036 case 'A': { // array 1037 var size = parseInt(func.substr(i)); 1038 i += size.toString().length; 1039 if (func[i] !== '_') throw '?'; 1040 i++; // skip _ 1041 list.push(parse(true, 1, true)[0] + ' [' + size + ']'); 1042 break; 1043 } 1044 case 'E': break paramLoop; 1045 default: ret += '?' + c; break paramLoop; 1046 } 1047 } 1048 } 1049 if (!allowVoid && list.length === 1 && list[0] === 'void') list = []; // avoid (void) 1050 if (rawList) { 1051 if (ret) { 1052 list.push(ret + '?'); 1053 } 1054 return list; 1055 } else { 1056 return ret + flushList(); 1057 } 1058 } 1059 try { 1060 // Special-case the entry point, since its name differs from other name mangling. 1061 if (func == 'Object._main' || func == '_main') { 1062 return 'main()'; 1063 } 1064 if (typeof func === 'number') func = Pointer_stringify(func); 1065 if (func[0] !== '_') return func; 1066 if (func[1] !== '_') return func; // C function 1067 if (func[2] !== 'Z') return func; 1068 switch (func[3]) { 1069 case 'n': return 'operator new()'; 1070 case 'd': return 'operator delete()'; 1071 } 1072 return parse(); 1073 } catch(e) { 1074 return func; 1075 } 1076} 1077 1078function demangleAll(text) { 1079 return text.replace(/__Z[\w\d_]+/g, function(x) { var y = demangle(x); return x === y ? x : (x + ' [' + y + ']') }); 1080} 1081 1082function stackTrace() { 1083 var stack = new Error().stack; 1084 return stack ? demangleAll(stack) : '(no stack trace available)'; // Stack trace is not available at least on IE10 and Safari 6. 1085} 1086 1087// Memory management 1088 1089var PAGE_SIZE = 4096; 1090function alignMemoryPage(x) { 1091 return (x+4095)&-4096; 1092} 1093 1094var HEAP; 1095var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64; 1096 1097var STATIC_BASE = 0, STATICTOP = 0, staticSealed = false; // static area 1098var STACK_BASE = 0, STACKTOP = 0, STACK_MAX = 0; // stack area 1099var DYNAMIC_BASE = 0, DYNAMICTOP = 0; // dynamic area handled by sbrk 1100 1101function enlargeMemory() { 1102 abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL_MEMORY + ', (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.'); 1103} 1104 1105var TOTAL_STACK = Module['TOTAL_STACK'] || 5242880; 1106var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 134217728; 1107var FAST_MEMORY = Module['FAST_MEMORY'] || 2097152; 1108 1109var totalMemory = 4096; 1110while (totalMemory < TOTAL_MEMORY || totalMemory < 2*TOTAL_STACK) { 1111 if (totalMemory < 16*1024*1024) { 1112 totalMemory *= 2; 1113 } else { 1114 totalMemory += 16*1024*1024 1115 } 1116} 1117if (totalMemory !== TOTAL_MEMORY) { 1118 Module.printErr('increasing TOTAL_MEMORY to ' + totalMemory + ' to be more reasonable'); 1119 TOTAL_MEMORY = totalMemory; 1120} 1121 1122// Initialize the runtime's memory 1123// check for full engine support (use string 'subarray' to avoid closure compiler confusion) 1124assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']), 1125 'JS engine does not provide full typed array support'); 1126 1127var buffer = new ArrayBuffer(TOTAL_MEMORY); 1128HEAP8 = new Int8Array(buffer); 1129HEAP16 = new Int16Array(buffer); 1130HEAP32 = new Int32Array(buffer); 1131HEAPU8 = new Uint8Array(buffer); 1132HEAPU16 = new Uint16Array(buffer); 1133HEAPU32 = new Uint32Array(buffer); 1134HEAPF32 = new Float32Array(buffer); 1135HEAPF64 = new Float64Array(buffer); 1136 1137// Endianness check (note: assumes compiler arch was little-endian) 1138HEAP32[0] = 255; 1139assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system'); 1140 1141Module['HEAP'] = HEAP; 1142Module['HEAP8'] = HEAP8; 1143Module['HEAP16'] = HEAP16; 1144Module['HEAP32'] = HEAP32; 1145Module['HEAPU8'] = HEAPU8; 1146Module['HEAPU16'] = HEAPU16; 1147Module['HEAPU32'] = HEAPU32; 1148Module['HEAPF32'] = HEAPF32; 1149Module['HEAPF64'] = HEAPF64; 1150 1151function callRuntimeCallbacks(callbacks) { 1152 while(callbacks.length > 0) { 1153 var callback = callbacks.shift(); 1154 if (typeof callback == 'function') { 1155 callback(); 1156 continue; 1157 } 1158 var func = callback.func; 1159 if (typeof func === 'number') { 1160 if (callback.arg === undefined) { 1161 Runtime.dynCall('v', func); 1162 } else { 1163 Runtime.dynCall('vi', func, [callback.arg]); 1164 } 1165 } else { 1166 func(callback.arg === undefined ? null : callback.arg); 1167 } 1168 } 1169} 1170 1171var __ATPRERUN__ = []; // functions called before the runtime is initialized 1172var __ATINIT__ = []; // functions called during startup 1173var __ATMAIN__ = []; // functions called when main() is to be run 1174var __ATEXIT__ = []; // functions called during shutdown 1175var __ATPOSTRUN__ = []; // functions called after the runtime has exited 1176 1177var runtimeInitialized = false; 1178 1179function preRun() { 1180 // compatibility - merge in anything from Module['preRun'] at this time 1181 if (Module['preRun']) { 1182 if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']]; 1183 while (Module['preRun'].length) { 1184 addOnPreRun(Module['preRun'].shift()); 1185 } 1186 } 1187 callRuntimeCallbacks(__ATPRERUN__); 1188} 1189 1190function ensureInitRuntime() { 1191 if (runtimeInitialized) return; 1192 runtimeInitialized = true; 1193 callRuntimeCallbacks(__ATINIT__); 1194} 1195 1196function preMain() { 1197 callRuntimeCallbacks(__ATMAIN__); 1198} 1199 1200function exitRuntime() { 1201 callRuntimeCallbacks(__ATEXIT__); 1202} 1203 1204function postRun() { 1205 // compatibility - merge in anything from Module['postRun'] at this time 1206 if (Module['postRun']) { 1207 if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']]; 1208 while (Module['postRun'].length) { 1209 addOnPostRun(Module['postRun'].shift()); 1210 } 1211 } 1212 callRuntimeCallbacks(__ATPOSTRUN__); 1213} 1214 1215function addOnPreRun(cb) { 1216 __ATPRERUN__.unshift(cb); 1217} 1218Module['addOnPreRun'] = Module.addOnPreRun = addOnPreRun; 1219 1220function addOnInit(cb) { 1221 __ATINIT__.unshift(cb); 1222} 1223Module['addOnInit'] = Module.addOnInit = addOnInit; 1224 1225function addOnPreMain(cb) { 1226 __ATMAIN__.unshift(cb); 1227} 1228Module['addOnPreMain'] = Module.addOnPreMain = addOnPreMain; 1229 1230function addOnExit(cb) { 1231 __ATEXIT__.unshift(cb); 1232} 1233Module['addOnExit'] = Module.addOnExit = addOnExit; 1234 1235function addOnPostRun(cb) { 1236 __ATPOSTRUN__.unshift(cb); 1237} 1238Module['addOnPostRun'] = Module.addOnPostRun = addOnPostRun; 1239 1240// Tools 1241 1242// This processes a JS string into a C-line array of numbers, 0-terminated. 1243// For LLVM-originating strings, see parser.js:parseLLVMString function 1244function intArrayFromString(stringy, dontAddNull, length /* optional */) { 1245 var ret = (new Runtime.UTF8Processor()).processJSString(stringy); 1246 if (length) { 1247 ret.length = length; 1248 } 1249 if (!dontAddNull) { 1250 ret.push(0); 1251 } 1252 return ret; 1253} 1254Module['intArrayFromString'] = intArrayFromString; 1255 1256function intArrayToString(array) { 1257 var ret = []; 1258 for (var i = 0; i < array.length; i++) { 1259 var chr = array[i]; 1260 if (chr > 0xFF) { 1261 chr &= 0xFF; 1262 } 1263 ret.push(String.fromCharCode(chr)); 1264 } 1265 return ret.join(''); 1266} 1267Module['intArrayToString'] = intArrayToString; 1268 1269// Write a Javascript array to somewhere in the heap 1270function writeStringToMemory(string, buffer, dontAddNull) { 1271 var array = intArrayFromString(string, dontAddNull); 1272 var i = 0; 1273 while (i < array.length) { 1274 var chr = array[i]; 1275 HEAP8[(((buffer)+(i))|0)]=chr; 1276 i = i + 1; 1277 } 1278} 1279Module['writeStringToMemory'] = writeStringToMemory; 1280 1281function writeArrayToMemory(array, buffer) { 1282 for (var i = 0; i < array.length; i++) { 1283 HEAP8[(((buffer)+(i))|0)]=array[i]; 1284 } 1285} 1286Module['writeArrayToMemory'] = writeArrayToMemory; 1287 1288function writeAsciiToMemory(str, buffer, dontAddNull) { 1289 for (var i = 0; i < str.length; i++) { 1290 HEAP8[(((buffer)+(i))|0)]=str.charCodeAt(i); 1291 } 1292 if (!dontAddNull) HEAP8[(((buffer)+(str.length))|0)]=0; 1293} 1294Module['writeAsciiToMemory'] = writeAsciiToMemory; 1295 1296function unSign(value, bits, ignore) { 1297 if (value >= 0) { 1298 return value; 1299 } 1300 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 1301 : Math.pow(2, bits) + value; 1302} 1303function reSign(value, bits, ignore) { 1304 if (value <= 0) { 1305 return value; 1306 } 1307 var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32 1308 : Math.pow(2, bits-1); 1309 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 1310 // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors 1311 // TODO: In i64 mode 1, resign the two parts separately and safely 1312 value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts 1313 } 1314 return value; 1315} 1316 1317// check for imul support, and also for correctness ( https://bugs.webkit.org/show_bug.cgi?id=126345 ) 1318if (!Math['imul'] || Math['imul'](0xffffffff, 5) !== -5) Math['imul'] = function imul(a, b) { 1319 var ah = a >>> 16; 1320 var al = a & 0xffff; 1321 var bh = b >>> 16; 1322 var bl = b & 0xffff; 1323 return (al*bl + ((ah*bl + al*bh) << 16))|0; 1324}; 1325Math.imul = Math['imul']; 1326 1327 1328var Math_abs = Math.abs; 1329var Math_cos = Math.cos; 1330var Math_sin = Math.sin; 1331var Math_tan = Math.tan; 1332var Math_acos = Math.acos; 1333var Math_asin = Math.asin; 1334var Math_atan = Math.atan; 1335var Math_atan2 = Math.atan2; 1336var Math_exp = Math.exp; 1337var Math_log = Math.log; 1338var Math_sqrt = Math.sqrt; 1339var Math_ceil = Math.ceil; 1340var Math_floor = Math.floor; 1341var Math_pow = Math.pow; 1342var Math_imul = Math.imul; 1343var Math_fround = Math.fround; 1344var Math_min = Math.min; 1345 1346// A counter of dependencies for calling run(). If we need to 1347// do asynchronous work before running, increment this and 1348// decrement it. Incrementing must happen in a place like 1349// PRE_RUN_ADDITIONS (used by emcc to add file preloading). 1350// Note that you can add dependencies in preRun, even though 1351// it happens right before run - run will be postponed until 1352// the dependencies are met. 1353var runDependencies = 0; 1354var runDependencyWatcher = null; 1355var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled 1356 1357function addRunDependency(id) { 1358 runDependencies++; 1359 if (Module['monitorRunDependencies']) { 1360 Module['monitorRunDependencies'](runDependencies); 1361 } 1362} 1363Module['addRunDependency'] = addRunDependency; 1364function removeRunDependency(id) { 1365 runDependencies--; 1366 if (Module['monitorRunDependencies']) { 1367 Module['monitorRunDependencies'](runDependencies); 1368 } 1369 if (runDependencies == 0) { 1370 if (runDependencyWatcher !== null) { 1371 clearInterval(runDependencyWatcher); 1372 runDependencyWatcher = null; 1373 } 1374 if (dependenciesFulfilled) { 1375 var callback = dependenciesFulfilled; 1376 dependenciesFulfilled = null; 1377 callback(); // can add another dependenciesFulfilled 1378 } 1379 } 1380} 1381Module['removeRunDependency'] = removeRunDependency; 1382 1383Module["preloadedImages"] = {}; // maps url to image data 1384Module["preloadedAudios"] = {}; // maps url to audio data 1385 1386 1387var memoryInitializer = null; 1388 1389// === Body === 1390 1391 1392 1393 1394 1395STATIC_BASE = 8; 1396 1397STATICTOP = STATIC_BASE + Runtime.alignMemory(547); 1398/* global initializers */ __ATINIT__.push(); 1399 1400 1401/* memory initializer */ allocate([101,114,114,111,114,58,32,37,100,10,0,0,0,0,0,0,80,102,97,110,110,107,117,99,104,101,110,40,37,100,41,32,61,32,37,100,46,10,0,0,37,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], "i8", ALLOC_NONE, Runtime.GLOBAL_BASE); 1402 1403 1404 1405 1406var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8); 1407 1408assert(tempDoublePtr % 8 == 0); 1409 1410function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much 1411 1412 HEAP8[tempDoublePtr] = HEAP8[ptr]; 1413 1414 HEAP8[tempDoublePtr+1] = HEAP8[ptr+1]; 1415 1416 HEAP8[tempDoublePtr+2] = HEAP8[ptr+2]; 1417 1418 HEAP8[tempDoublePtr+3] = HEAP8[ptr+3]; 1419 1420} 1421 1422function copyTempDouble(ptr) { 1423 1424 HEAP8[tempDoublePtr] = HEAP8[ptr]; 1425 1426 HEAP8[tempDoublePtr+1] = HEAP8[ptr+1]; 1427 1428 HEAP8[tempDoublePtr+2] = HEAP8[ptr+2]; 1429 1430 HEAP8[tempDoublePtr+3] = HEAP8[ptr+3]; 1431 1432 HEAP8[tempDoublePtr+4] = HEAP8[ptr+4]; 1433 1434 HEAP8[tempDoublePtr+5] = HEAP8[ptr+5]; 1435 1436 HEAP8[tempDoublePtr+6] = HEAP8[ptr+6]; 1437 1438 HEAP8[tempDoublePtr+7] = HEAP8[ptr+7]; 1439 1440} 1441 1442 1443 1444 1445 1446 1447 var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86}; 1448 1449 var ERRNO_MESSAGES={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"}; 1450 1451 1452 var ___errno_state=0;function ___setErrNo(value) { 1453 // For convenient setting and returning of errno. 1454 HEAP32[((___errno_state)>>2)]=value; 1455 return value; 1456 } 1457 1458 var PATH={splitPath:function (filename) { 1459 var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; 1460 return splitPathRe.exec(filename).slice(1); 1461 },normalizeArray:function (parts, allowAboveRoot) { 1462 // if the path tries to go above the root, `up` ends up > 0 1463 var up = 0; 1464 for (var i = parts.length - 1; i >= 0; i--) { 1465 var last = parts[i]; 1466 if (last === '.') { 1467 parts.splice(i, 1); 1468 } else if (last === '..') { 1469 parts.splice(i, 1); 1470 up++; 1471 } else if (up) { 1472 parts.splice(i, 1); 1473 up--; 1474 } 1475 } 1476 // if the path is allowed to go above the root, restore leading ..s 1477 if (allowAboveRoot) { 1478 for (; up--; up) { 1479 parts.unshift('..'); 1480 } 1481 } 1482 return parts; 1483 },normalize:function (path) { 1484 var isAbsolute = path.charAt(0) === '/', 1485 trailingSlash = path.substr(-1) === '/'; 1486 // Normalize the path 1487 path = PATH.normalizeArray(path.split('/').filter(function(p) { 1488 return !!p; 1489 }), !isAbsolute).join('/'); 1490 if (!path && !isAbsolute) { 1491 path = '.'; 1492 } 1493 if (path && trailingSlash) { 1494 path += '/'; 1495 } 1496 return (isAbsolute ? '/' : '') + path; 1497 },dirname:function (path) { 1498 var result = PATH.splitPath(path), 1499 root = result[0], 1500 dir = result[1]; 1501 if (!root && !dir) { 1502 // No dirname whatsoever 1503 return '.'; 1504 } 1505 if (dir) { 1506 // It has a dirname, strip trailing slash 1507 dir = dir.substr(0, dir.length - 1); 1508 } 1509 return root + dir; 1510 },basename:function (path) { 1511 // EMSCRIPTEN return '/'' for '/', not an empty string 1512 if (path === '/') return '/'; 1513 var lastSlash = path.lastIndexOf('/'); 1514 if (lastSlash === -1) return path; 1515 return path.substr(lastSlash+1); 1516 },extname:function (path) { 1517 return PATH.splitPath(path)[3]; 1518 },join:function () { 1519 var paths = Array.prototype.slice.call(arguments, 0); 1520 return PATH.normalize(paths.join('/')); 1521 },join2:function (l, r) { 1522 return PATH.normalize(l + '/' + r); 1523 },resolve:function () { 1524 var resolvedPath = '', 1525 resolvedAbsolute = false; 1526 for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { 1527 var path = (i >= 0) ? arguments[i] : FS.cwd(); 1528 // Skip empty and invalid entries 1529 if (typeof path !== 'string') { 1530 throw new TypeError('Arguments to path.resolve must be strings'); 1531 } else if (!path) { 1532 continue; 1533 } 1534 resolvedPath = path + '/' + resolvedPath; 1535 resolvedAbsolute = path.charAt(0) === '/'; 1536 } 1537 // At this point the path should be resolved to a full absolute path, but 1538 // handle relative paths to be safe (might happen when process.cwd() fails) 1539 resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) { 1540 return !!p; 1541 }), !resolvedAbsolute).join('/'); 1542 return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; 1543 },relative:function (from, to) { 1544 from = PATH.resolve(from).substr(1); 1545 to = PATH.resolve(to).substr(1); 1546 function trim(arr) { 1547 var start = 0; 1548 for (; start < arr.length; start++) { 1549 if (arr[start] !== '') break; 1550 } 1551 var end = arr.length - 1; 1552 for (; end >= 0; end--) { 1553 if (arr[end] !== '') break; 1554 } 1555 if (start > end) return []; 1556 return arr.slice(start, end - start + 1); 1557 } 1558 var fromParts = trim(from.split('/')); 1559 var toParts = trim(to.split('/')); 1560 var length = Math.min(fromParts.length, toParts.length); 1561 var samePartsLength = length; 1562 for (var i = 0; i < length; i++) { 1563 if (fromParts[i] !== toParts[i]) { 1564 samePartsLength = i; 1565 break; 1566 } 1567 } 1568 var outputParts = []; 1569 for (var i = samePartsLength; i < fromParts.length; i++) { 1570 outputParts.push('..'); 1571 } 1572 outputParts = outputParts.concat(toParts.slice(samePartsLength)); 1573 return outputParts.join('/'); 1574 }}; 1575 1576 var TTY={ttys:[],init:function () { 1577 // https://github.com/kripken/emscripten/pull/1555 1578 // if (ENVIRONMENT_IS_NODE) { 1579 // // currently, FS.init does not distinguish if process.stdin is a file or TTY 1580 // // device, it always assumes it's a TTY device. because of this, we're forcing 1581 // // process.stdin to UTF8 encoding to at least make stdin reading compatible 1582 // // with text files until FS.init can be refactored. 1583 // process['stdin']['setEncoding']('utf8'); 1584 // } 1585 },shutdown:function () { 1586 // https://github.com/kripken/emscripten/pull/1555 1587 // if (ENVIRONMENT_IS_NODE) { 1588 // // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)? 1589 // // 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 1590 // // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists? 1591 // // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle 1592 // // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call 1593 // process['stdin']['pause'](); 1594 // } 1595 },register:function (dev, ops) { 1596 TTY.ttys[dev] = { input: [], output: [], ops: ops }; 1597 FS.registerDevice(dev, TTY.stream_ops); 1598 },stream_ops:{open:function (stream) { 1599 var tty = TTY.ttys[stream.node.rdev]; 1600 if (!tty) { 1601 throw new FS.ErrnoError(ERRNO_CODES.ENODEV); 1602 } 1603 stream.tty = tty; 1604 stream.seekable = false; 1605 },close:function (stream) { 1606 // flush any pending line data 1607 if (stream.tty.output.length) { 1608 stream.tty.ops.put_char(stream.tty, 10); 1609 } 1610 },read:function (stream, buffer, offset, length, pos /* ignored */) { 1611 if (!stream.tty || !stream.tty.ops.get_char) { 1612 throw new FS.ErrnoError(ERRNO_CODES.ENXIO); 1613 } 1614 var bytesRead = 0; 1615 for (var i = 0; i < length; i++) { 1616 var result; 1617 try { 1618 result = stream.tty.ops.get_char(stream.tty); 1619 } catch (e) { 1620 throw new FS.ErrnoError(ERRNO_CODES.EIO); 1621 } 1622 if (result === undefined && bytesRead === 0) { 1623 throw new FS.ErrnoError(ERRNO_CODES.EAGAIN); 1624 } 1625 if (result === null || result === undefined) break; 1626 bytesRead++; 1627 buffer[offset+i] = result; 1628 } 1629 if (bytesRead) { 1630 stream.node.timestamp = Date.now(); 1631 } 1632 return bytesRead; 1633 },write:function (stream, buffer, offset, length, pos) { 1634 if (!stream.tty || !stream.tty.ops.put_char) { 1635 throw new FS.ErrnoError(ERRNO_CODES.ENXIO); 1636 } 1637 for (var i = 0; i < length; i++) { 1638 try { 1639 stream.tty.ops.put_char(stream.tty, buffer[offset+i]); 1640 } catch (e) { 1641 throw new FS.ErrnoError(ERRNO_CODES.EIO); 1642 } 1643 } 1644 if (length) { 1645 stream.node.timestamp = Date.now(); 1646 } 1647 return i; 1648 }},default_tty_ops:{get_char:function (tty) { 1649 if (!tty.input.length) { 1650 var result = null; 1651 if (ENVIRONMENT_IS_NODE) { 1652 result = process['stdin']['read'](); 1653 if (!result) { 1654 if (process['stdin']['_readableState'] && process['stdin']['_readableState']['ended']) { 1655 return null; // EOF 1656 } 1657 return undefined; // no data available 1658 } 1659 } else if (typeof window != 'undefined' && 1660 typeof window.prompt == 'function') { 1661 // Browser. 1662 result = window.prompt('Input: '); // returns null on cancel 1663 if (result !== null) { 1664 result += '\n'; 1665 } 1666 } else if (typeof readline == 'function') { 1667 // Command line. 1668 result = readline(); 1669 if (result !== null) { 1670 result += '\n'; 1671 } 1672 } 1673 if (!result) { 1674 return null; 1675 } 1676 tty.input = intArrayFromString(result, true); 1677 } 1678 return tty.input.shift(); 1679 },put_char:function (tty, val) { 1680 if (val === null || val === 10) { 1681 Module['print'](tty.output.join('')); 1682 tty.output = []; 1683 } else { 1684 tty.output.push(TTY.utf8.processCChar(val)); 1685 } 1686 }},default_tty1_ops:{put_char:function (tty, val) { 1687 if (val === null || val === 10) { 1688 Module['printErr'](tty.output.join('')); 1689 tty.output = []; 1690 } else { 1691 tty.output.push(TTY.utf8.processCChar(val)); 1692 } 1693 }}}; 1694 1695 var MEMFS={ops_table:null,CONTENT_OWNING:1,CONTENT_FLEXIBLE:2,CONTENT_FIXED:3,mount:function (mount) { 1696 return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0); 1697 },createNode:function (parent, name, mode, dev) { 1698 if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { 1699 // no supported 1700 throw new FS.ErrnoError(ERRNO_CODES.EPERM); 1701 } 1702 if (!MEMFS.ops_table) { 1703 MEMFS.ops_table = { 1704 dir: { 1705 node: { 1706 getattr: MEMFS.node_ops.getattr, 1707 setattr: MEMFS.node_ops.setattr, 1708 lookup: MEMFS.node_ops.lookup, 1709 mknod: MEMFS.node_ops.mknod, 1710 rename: MEMFS.node_ops.rename, 1711 unlink: MEMFS.node_ops.unlink, 1712 rmdir: MEMFS.node_ops.rmdir, 1713 readdir: MEMFS.node_ops.readdir, 1714 symlink: MEMFS.node_ops.symlink 1715 }, 1716 stream: { 1717 llseek: MEMFS.stream_ops.llseek 1718 } 1719 }, 1720 file: { 1721 node: { 1722 getattr: MEMFS.node_ops.getattr, 1723 setattr: MEMFS.node_ops.setattr 1724 }, 1725 stream: { 1726 llseek: MEMFS.stream_ops.llseek, 1727 read: MEMFS.stream_ops.read, 1728 write: MEMFS.stream_ops.write, 1729 allocate: MEMFS.stream_ops.allocate, 1730 mmap: MEMFS.stream_ops.mmap 1731 } 1732 }, 1733 link: { 1734 node: { 1735 getattr: MEMFS.node_ops.getattr, 1736 setattr: MEMFS.node_ops.setattr, 1737 readlink: MEMFS.node_ops.readlink 1738 }, 1739 stream: {} 1740 }, 1741 chrdev: { 1742 node: { 1743 getattr: MEMFS.node_ops.getattr, 1744 setattr: MEMFS.node_ops.setattr 1745 }, 1746 stream: FS.chrdev_stream_ops 1747 }, 1748 }; 1749 } 1750 var node = FS.createNode(parent, name, mode, dev); 1751 if (FS.isDir(node.mode)) { 1752 node.node_ops = MEMFS.ops_table.dir.node; 1753 node.stream_ops = MEMFS.ops_table.dir.stream; 1754 node.contents = {}; 1755 } else if (FS.isFile(node.mode)) { 1756 node.node_ops = MEMFS.ops_table.file.node; 1757 node.stream_ops = MEMFS.ops_table.file.stream; 1758 node.contents = []; 1759 node.contentMode = MEMFS.CONTENT_FLEXIBLE; 1760 } else if (FS.isLink(node.mode)) { 1761 node.node_ops = MEMFS.ops_table.link.node; 1762 node.stream_ops = MEMFS.ops_table.link.stream; 1763 } else if (FS.isChrdev(node.mode)) { 1764 node.node_ops = MEMFS.ops_table.chrdev.node; 1765 node.stream_ops = MEMFS.ops_table.chrdev.stream; 1766 } 1767 node.timestamp = Date.now(); 1768 // add the new node to the parent 1769 if (parent) { 1770 parent.contents[name] = node; 1771 } 1772 return node; 1773 },ensureFlexible:function (node) { 1774 if (node.contentMode !== MEMFS.CONTENT_FLEXIBLE) { 1775 var contents = node.contents; 1776 node.contents = Array.prototype.slice.call(contents); 1777 node.contentMode = MEMFS.CONTENT_FLEXIBLE; 1778 } 1779 },node_ops:{getattr:function (node) { 1780 var attr = {}; 1781 // device numbers reuse inode numbers. 1782 attr.dev = FS.isChrdev(node.mode) ? node.id : 1; 1783 attr.ino = node.id; 1784 attr.mode = node.mode; 1785 attr.nlink = 1; 1786 attr.uid = 0; 1787 attr.gid = 0; 1788 attr.rdev = node.rdev; 1789 if (FS.isDir(node.mode)) { 1790 attr.size = 4096; 1791 } else if (FS.isFile(node.mode)) { 1792 attr.size = node.contents.length; 1793 } else if (FS.isLink(node.mode)) { 1794 attr.size = node.link.length; 1795 } else { 1796 attr.size = 0; 1797 } 1798 attr.atime = new Date(node.timestamp); 1799 attr.mtime = new Date(node.timestamp); 1800 attr.ctime = new Date(node.timestamp); 1801 // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize), 1802 // but this is not required by the standard. 1803 attr.blksize = 4096; 1804 attr.blocks = Math.ceil(attr.size / attr.blksize); 1805 return attr; 1806 },setattr:function (node, attr) { 1807 if (attr.mode !== undefined) { 1808 node.mode = attr.mode; 1809 } 1810 if (attr.timestamp !== undefined) { 1811 node.timestamp = attr.timestamp; 1812 } 1813 if (attr.size !== undefined) { 1814 MEMFS.ensureFlexible(node); 1815 var contents = node.contents; 1816 if (attr.size < contents.length) contents.length = attr.size; 1817 else while (attr.size > contents.length) contents.push(0); 1818 } 1819 },lookup:function (parent, name) { 1820 throw FS.genericErrors[ERRNO_CODES.ENOENT]; 1821 },mknod:function (parent, name, mode, dev) { 1822 return MEMFS.createNode(parent, name, mode, dev); 1823 },rename:function (old_node, new_dir, new_name) { 1824 // if we're overwriting a directory at new_name, make sure it's empty. 1825 if (FS.isDir(old_node.mode)) { 1826 var new_node; 1827 try { 1828 new_node = FS.lookupNode(new_dir, new_name); 1829 } catch (e) { 1830 } 1831 if (new_node) { 1832 for (var i in new_node.contents) { 1833 throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY); 1834 } 1835 } 1836 } 1837 // do the internal rewiring 1838 delete old_node.parent.contents[old_node.name]; 1839 old_node.name = new_name; 1840 new_dir.contents[new_name] = old_node; 1841 old_node.parent = new_dir; 1842 },unlink:function (parent, name) { 1843 delete parent.contents[name]; 1844 },rmdir:function (parent, name) { 1845 var node = FS.lookupNode(parent, name); 1846 for (var i in node.contents) { 1847 throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY); 1848 } 1849 delete parent.contents[name]; 1850 },readdir:function (node) { 1851 var entries = ['.', '..'] 1852 for (var key in node.contents) { 1853 if (!node.contents.hasOwnProperty(key)) { 1854 continue; 1855 } 1856 entries.push(key); 1857 } 1858 return entries; 1859 },symlink:function (parent, newname, oldpath) { 1860 var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0); 1861 node.link = oldpath; 1862 return node; 1863 },readlink:function (node) { 1864 if (!FS.isLink(node.mode)) { 1865 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 1866 } 1867 return node.link; 1868 }},stream_ops:{read:function (stream, buffer, offset, length, position) { 1869 var contents = stream.node.contents; 1870 if (position >= contents.length) 1871 return 0; 1872 var size = Math.min(contents.length - position, length); 1873 assert(size >= 0); 1874 if (size > 8 && contents.subarray) { // non-trivial, and typed array 1875 buffer.set(contents.subarray(position, position + size), offset); 1876 } else 1877 { 1878 for (var i = 0; i < size; i++) { 1879 buffer[offset + i] = contents[position + i]; 1880 } 1881 } 1882 return size; 1883 },write:function (stream, buffer, offset, length, position, canOwn) { 1884 var node = stream.node; 1885 node.timestamp = Date.now(); 1886 var contents = node.contents; 1887 if (length && contents.length === 0 && position === 0 && buffer.subarray) { 1888 // just replace it with the new data 1889 if (canOwn && offset === 0) { 1890 node.contents = buffer; // this could be a subarray of Emscripten HEAP, or allocated from some other source. 1891 node.contentMode = (buffer.buffer === HEAP8.buffer) ? MEMFS.CONTENT_OWNING : MEMFS.CONTENT_FIXED; 1892 } else { 1893 node.contents = new Uint8Array(buffer.subarray(offset, offset+length)); 1894 node.contentMode = MEMFS.CONTENT_FIXED; 1895 } 1896 return length; 1897 } 1898 MEMFS.ensureFlexible(node); 1899 var contents = node.contents; 1900 while (contents.length < position) contents.push(0); 1901 for (var i = 0; i < length; i++) { 1902 contents[position + i] = buffer[offset + i]; 1903 } 1904 return length; 1905 },llseek:function (stream, offset, whence) { 1906 var position = offset; 1907 if (whence === 1) { // SEEK_CUR. 1908 position += stream.position; 1909 } else if (whence === 2) { // SEEK_END. 1910 if (FS.isFile(stream.node.mode)) { 1911 position += stream.node.contents.length; 1912 } 1913 } 1914 if (position < 0) { 1915 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 1916 } 1917 stream.ungotten = []; 1918 stream.position = position; 1919 return position; 1920 },allocate:function (stream, offset, length) { 1921 MEMFS.ensureFlexible(stream.node); 1922 var contents = stream.node.contents; 1923 var limit = offset + length; 1924 while (limit > contents.length) contents.push(0); 1925 },mmap:function (stream, buffer, offset, length, position, prot, flags) { 1926 if (!FS.isFile(stream.node.mode)) { 1927 throw new FS.ErrnoError(ERRNO_CODES.ENODEV); 1928 } 1929 var ptr; 1930 var allocated; 1931 var contents = stream.node.contents; 1932 // Only make a new copy when MAP_PRIVATE is specified. 1933 if ( !(flags & 2) && 1934 (contents.buffer === buffer || contents.buffer === buffer.buffer) ) { 1935 // We can't emulate MAP_SHARED when the file is not backed by the buffer 1936 // we're mapping to (e.g. the HEAP buffer). 1937 allocated = false; 1938 ptr = contents.byteOffset; 1939 } else { 1940 // Try to avoid unnecessary slices. 1941 if (position > 0 || position + length < contents.length) { 1942 if (contents.subarray) { 1943 contents = contents.subarray(position, position + length); 1944 } else { 1945 contents = Array.prototype.slice.call(contents, position, position + length); 1946 } 1947 } 1948 allocated = true; 1949 ptr = _malloc(length); 1950 if (!ptr) { 1951 throw new FS.ErrnoError(ERRNO_CODES.ENOMEM); 1952 } 1953 buffer.set(contents, ptr); 1954 } 1955 return { ptr: ptr, allocated: allocated }; 1956 }}}; 1957 1958 var IDBFS={dbs:{},indexedDB:function () { 1959 return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; 1960 },DB_VERSION:21,DB_STORE_NAME:"FILE_DATA",mount:function (mount) { 1961 // reuse all of the core MEMFS functionality 1962 return MEMFS.mount.apply(null, arguments); 1963 },syncfs:function (mount, populate, callback) { 1964 IDBFS.getLocalSet(mount, function(err, local) { 1965 if (err) return callback(err); 1966 1967 IDBFS.getRemoteSet(mount, function(err, remote) { 1968 if (err) return callback(err); 1969 1970 var src = populate ? remote : local; 1971 var dst = populate ? local : remote; 1972 1973 IDBFS.reconcile(src, dst, callback); 1974 }); 1975 }); 1976 },getDB:function (name, callback) { 1977 // check the cache first 1978 var db = IDBFS.dbs[name]; 1979 if (db) { 1980 return callback(null, db); 1981 } 1982 1983 var req; 1984 try { 1985 req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION); 1986 } catch (e) { 1987 return callback(e); 1988 } 1989 req.onupgradeneeded = function(e) { 1990 var db = e.target.result; 1991 var transaction = e.target.transaction; 1992 1993 var fileStore; 1994 1995 if (db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) { 1996 fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME); 1997 } else { 1998 fileStore = db.createObjectStore(IDBFS.DB_STORE_NAME); 1999 } 2000 2001 fileStore.createIndex('timestamp', 'timestamp', { unique: false }); 2002 }; 2003 req.onsuccess = function() { 2004 db = req.result; 2005 2006 // add to the cache 2007 IDBFS.dbs[name] = db; 2008 callback(null, db); 2009 }; 2010 req.onerror = function() { 2011 callback(this.error); 2012 }; 2013 },getLocalSet:function (mount, callback) { 2014 var entries = {}; 2015 2016 function isRealDir(p) { 2017 return p !== '.' && p !== '..'; 2018 }; 2019 function toAbsolute(root) { 2020 return function(p) { 2021 return PATH.join2(root, p); 2022 } 2023 }; 2024 2025 var check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint)); 2026 2027 while (check.length) { 2028 var path = check.pop(); 2029 var stat; 2030 2031 try { 2032 stat = FS.stat(path); 2033 } catch (e) { 2034 return callback(e); 2035 } 2036 2037 if (FS.isDir(stat.mode)) { 2038 check.push.apply(check, FS.readdir(path).filter(isRealDir).map(toAbsolute(path))); 2039 } 2040 2041 entries[path] = { timestamp: stat.mtime }; 2042 } 2043 2044 return callback(null, { type: 'local', entries: entries }); 2045 },getRemoteSet:function (mount, callback) { 2046 var entries = {}; 2047 2048 IDBFS.getDB(mount.mountpoint, function(err, db) { 2049 if (err) return callback(err); 2050 2051 var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readonly'); 2052 transaction.onerror = function() { callback(this.error); }; 2053 2054 var store = transaction.objectStore(IDBFS.DB_STORE_NAME); 2055 var index = store.index('timestamp'); 2056 2057 index.openKeyCursor().onsuccess = function(event) { 2058 var cursor = event.target.result; 2059 2060 if (!cursor) { 2061 return callback(null, { type: 'remote', db: db, entries: entries }); 2062 } 2063 2064 entries[cursor.primaryKey] = { timestamp: cursor.key }; 2065 2066 cursor.continue(); 2067 }; 2068 }); 2069 },loadLocalEntry:function (path, callback) { 2070 var stat, node; 2071 2072 try { 2073 var lookup = FS.lookupPath(path); 2074 node = lookup.node; 2075 stat = FS.stat(path); 2076 } catch (e) { 2077 return callback(e); 2078 } 2079 2080 if (FS.isDir(stat.mode)) { 2081 return callback(null, { timestamp: stat.mtime, mode: stat.mode }); 2082 } else if (FS.isFile(stat.mode)) { 2083 return callback(null, { timestamp: stat.mtime, mode: stat.mode, contents: node.contents }); 2084 } else { 2085 return callback(new Error('node type not supported')); 2086 } 2087 },storeLocalEntry:function (path, entry, callback) { 2088 try { 2089 if (FS.isDir(entry.mode)) { 2090 FS.mkdir(path, entry.mode); 2091 } else if (FS.isFile(entry.mode)) { 2092 FS.writeFile(path, entry.contents, { encoding: 'binary', canOwn: true }); 2093 } else { 2094 return callback(new Error('node type not supported')); 2095 } 2096 2097 FS.utime(path, entry.timestamp, entry.timestamp); 2098 } catch (e) { 2099 return callback(e); 2100 } 2101 2102 callback(null); 2103 },removeLocalEntry:function (path, callback) { 2104 try { 2105 var lookup = FS.lookupPath(path); 2106 var stat = FS.stat(path); 2107 2108 if (FS.isDir(stat.mode)) { 2109 FS.rmdir(path); 2110 } else if (FS.isFile(stat.mode)) { 2111 FS.unlink(path); 2112 } 2113 } catch (e) { 2114 return callback(e); 2115 } 2116 2117 callback(null); 2118 },loadRemoteEntry:function (store, path, callback) { 2119 var req = store.get(path); 2120 req.onsuccess = function(event) { callback(null, event.target.result); }; 2121 req.onerror = function() { callback(this.error); }; 2122 },storeRemoteEntry:function (store, path, entry, callback) { 2123 var req = store.put(entry, path); 2124 req.onsuccess = function() { callback(null); }; 2125 req.onerror = function() { callback(this.error); }; 2126 },removeRemoteEntry:function (store, path, callback) { 2127 var req = store.delete(path); 2128 req.onsuccess = function() { callback(null); }; 2129 req.onerror = function() { callback(this.error); }; 2130 },reconcile:function (src, dst, callback) { 2131 var total = 0; 2132 2133 var create = []; 2134 Object.keys(src.entries).forEach(function (key) { 2135 var e = src.entries[key]; 2136 var e2 = dst.entries[key]; 2137 if (!e2 || e.timestamp > e2.timestamp) { 2138 create.push(key); 2139 total++; 2140 } 2141 }); 2142 2143 var remove = []; 2144 Object.keys(dst.entries).forEach(function (key) { 2145 var e = dst.entries[key]; 2146 var e2 = src.entries[key]; 2147 if (!e2) { 2148 remove.push(key); 2149 total++; 2150 } 2151 }); 2152 2153 if (!total) { 2154 return callback(null); 2155 } 2156 2157 var errored = false; 2158 var completed = 0; 2159 var db = src.type === 'remote' ? src.db : dst.db; 2160 var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readwrite'); 2161 var store = transaction.objectStore(IDBFS.DB_STORE_NAME); 2162 2163 function done(err) { 2164 if (err) { 2165 if (!done.errored) { 2166 done.errored = true; 2167 return callback(err); 2168 } 2169 return; 2170 } 2171 if (++completed >= total) { 2172 return callback(null); 2173 } 2174 }; 2175 2176 transaction.onerror = function() { done(this.error); }; 2177 2178 // sort paths in ascending order so directory entries are created 2179 // before the files inside them 2180 create.sort().forEach(function (path) { 2181 if (dst.type === 'local') { 2182 IDBFS.loadRemoteEntry(store, path, function (err, entry) { 2183 if (err) return done(err); 2184 IDBFS.storeLocalEntry(path, entry, done); 2185 }); 2186 } else { 2187 IDBFS.loadLocalEntry(path, function (err, entry) { 2188 if (err) return done(err); 2189 IDBFS.storeRemoteEntry(store, path, entry, done); 2190 }); 2191 } 2192 }); 2193 2194 // sort paths in descending order so files are deleted before their 2195 // parent directories 2196 remove.sort().reverse().forEach(function(path) { 2197 if (dst.type === 'local') { 2198 IDBFS.removeLocalEntry(path, done); 2199 } else { 2200 IDBFS.removeRemoteEntry(store, path, done); 2201 } 2202 }); 2203 }}; 2204 2205 var NODEFS={isWindows:false,staticInit:function () { 2206 NODEFS.isWindows = !!process.platform.match(/^win/); 2207 },mount:function (mount) { 2208 assert(ENVIRONMENT_IS_NODE); 2209 return NODEFS.createNode(null, '/', NODEFS.getMode(mount.opts.root), 0); 2210 },createNode:function (parent, name, mode, dev) { 2211 if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) { 2212 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 2213 } 2214 var node = FS.createNode(parent, name, mode); 2215 node.node_ops = NODEFS.node_ops; 2216 node.stream_ops = NODEFS.stream_ops; 2217 return node; 2218 },getMode:function (path) { 2219 var stat; 2220 try { 2221 stat = fs.lstatSync(path); 2222 if (NODEFS.isWindows) { 2223 // On Windows, directories return permission bits 'rw-rw-rw-', even though they have 'rwxrwxrwx', so 2224 // propagate write bits to execute bits. 2225 stat.mode = stat.mode | ((stat.mode & 146) >> 1); 2226 } 2227 } catch (e) { 2228 if (!e.code) throw e; 2229 throw new FS.ErrnoError(ERRNO_CODES[e.code]); 2230 } 2231 return stat.mode; 2232 },realPath:function (node) { 2233 var parts = []; 2234 while (node.parent !== node) { 2235 parts.push(node.name); 2236 node = node.parent; 2237 } 2238 parts.push(node.mount.opts.root); 2239 parts.reverse(); 2240 return PATH.join.apply(null, parts); 2241 },flagsToPermissionStringMap:{0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"},flagsToPermissionString:function (flags) { 2242 if (flags in NODEFS.flagsToPermissionStringMap) { 2243 return NODEFS.flagsToPermissionStringMap[flags]; 2244 } else { 2245 return flags; 2246 } 2247 },node_ops:{getattr:function (node) { 2248 var path = NODEFS.realPath(node); 2249 var stat; 2250 try { 2251 stat = fs.lstatSync(path); 2252 } catch (e) { 2253 if (!e.code) throw e; 2254 throw new FS.ErrnoError(ERRNO_CODES[e.code]); 2255 } 2256 // node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake them with default blksize of 4096. 2257 // See http://support.microsoft.com/kb/140365 2258 if (NODEFS.isWindows && !stat.blksize) { 2259 stat.blksize = 4096; 2260 } 2261 if (NODEFS.isWindows && !stat.blocks) { 2262 stat.blocks = (stat.size+stat.blksize-1)/stat.blksize|0; 2263 } 2264 return { 2265 dev: stat.dev, 2266 ino: stat.ino, 2267 mode: stat.mode, 2268 nlink: stat.nlink, 2269 uid: stat.uid, 2270 gid: stat.gid, 2271 rdev: stat.rdev, 2272 size: stat.size, 2273 atime: stat.atime, 2274 mtime: stat.mtime, 2275 ctime: stat.ctime, 2276 blksize: stat.blksize, 2277 blocks: stat.blocks 2278 }; 2279 },setattr:function (node, attr) { 2280 var path = NODEFS.realPath(node); 2281 try { 2282 if (attr.mode !== undefined) { 2283 fs.chmodSync(path, attr.mode); 2284 // update the common node structure mode as well 2285 node.mode = attr.mode; 2286 } 2287 if (attr.timestamp !== undefined) { 2288 var date = new Date(attr.timestamp); 2289 fs.utimesSync(path, date, date); 2290 } 2291 if (attr.size !== undefined) { 2292 fs.truncateSync(path, attr.size); 2293 } 2294 } catch (e) { 2295 if (!e.code) throw e; 2296 throw new FS.ErrnoError(ERRNO_CODES[e.code]); 2297 } 2298 },lookup:function (parent, name) { 2299 var path = PATH.join2(NODEFS.realPath(parent), name); 2300 var mode = NODEFS.getMode(path); 2301 return NODEFS.createNode(parent, name, mode); 2302 },mknod:function (parent, name, mode, dev) { 2303 var node = NODEFS.createNode(parent, name, mode, dev); 2304 // create the backing node for this in the fs root as well 2305 var path = NODEFS.realPath(node); 2306 try { 2307 if (FS.isDir(node.mode)) { 2308 fs.mkdirSync(path, node.mode); 2309 } else { 2310 fs.writeFileSync(path, '', { mode: node.mode }); 2311 } 2312 } catch (e) { 2313 if (!e.code) throw e; 2314 throw new FS.ErrnoError(ERRNO_CODES[e.code]); 2315 } 2316 return node; 2317 },rename:function (oldNode, newDir, newName) { 2318 var oldPath = NODEFS.realPath(oldNode); 2319 var newPath = PATH.join2(NODEFS.realPath(newDir), newName); 2320 try { 2321 fs.renameSync(oldPath, newPath); 2322 } catch (e) { 2323 if (!e.code) throw e; 2324 throw new FS.ErrnoError(ERRNO_CODES[e.code]); 2325 } 2326 },unlink:function (parent, name) { 2327 var path = PATH.join2(NODEFS.realPath(parent), name); 2328 try { 2329 fs.unlinkSync(path); 2330 } catch (e) { 2331 if (!e.code) throw e; 2332 throw new FS.ErrnoError(ERRNO_CODES[e.code]); 2333 } 2334 },rmdir:function (parent, name) { 2335 var path = PATH.join2(NODEFS.realPath(parent), name); 2336 try { 2337 fs.rmdirSync(path); 2338 } catch (e) { 2339 if (!e.code) throw e; 2340 throw new FS.ErrnoError(ERRNO_CODES[e.code]); 2341 } 2342 },readdir:function (node) { 2343 var path = NODEFS.realPath(node); 2344 try { 2345 return fs.readdirSync(path); 2346 } catch (e) { 2347 if (!e.code) throw e; 2348 throw new FS.ErrnoError(ERRNO_CODES[e.code]); 2349 } 2350 },symlink:function (parent, newName, oldPath) { 2351 var newPath = PATH.join2(NODEFS.realPath(parent), newName); 2352 try { 2353 fs.symlinkSync(oldPath, newPath); 2354 } catch (e) { 2355 if (!e.code) throw e; 2356 throw new FS.ErrnoError(ERRNO_CODES[e.code]); 2357 } 2358 },readlink:function (node) { 2359 var path = NODEFS.realPath(node); 2360 try { 2361 return fs.readlinkSync(path); 2362 } catch (e) { 2363 if (!e.code) throw e; 2364 throw new FS.ErrnoError(ERRNO_CODES[e.code]); 2365 } 2366 }},stream_ops:{open:function (stream) { 2367 var path = NODEFS.realPath(stream.node); 2368 try { 2369 if (FS.isFile(stream.node.mode)) { 2370 stream.nfd = fs.openSync(path, NODEFS.flagsToPermissionString(stream.flags)); 2371 } 2372 } catch (e) { 2373 if (!e.code) throw e; 2374 throw new FS.ErrnoError(ERRNO_CODES[e.code]); 2375 } 2376 },close:function (stream) { 2377 try { 2378 if (FS.isFile(stream.node.mode) && stream.nfd) { 2379 fs.closeSync(stream.nfd); 2380 } 2381 } catch (e) { 2382 if (!e.code) throw e; 2383 throw new FS.ErrnoError(ERRNO_CODES[e.code]); 2384 } 2385 },read:function (stream, buffer, offset, length, position) { 2386 // FIXME this is terrible. 2387 var nbuffer = new Buffer(length); 2388 var res; 2389 try { 2390 res = fs.readSync(stream.nfd, nbuffer, 0, length, position); 2391 } catch (e) { 2392 throw new FS.ErrnoError(ERRNO_CODES[e.code]); 2393 } 2394 if (res > 0) { 2395 for (var i = 0; i < res; i++) { 2396 buffer[offset + i] = nbuffer[i]; 2397 } 2398 } 2399 return res; 2400 },write:function (stream, buffer, offset, length, position) { 2401 // FIXME this is terrible. 2402 var nbuffer = new Buffer(buffer.subarray(offset, offset + length)); 2403 var res; 2404 try { 2405 res = fs.writeSync(stream.nfd, nbuffer, 0, length, position); 2406 } catch (e) { 2407 throw new FS.ErrnoError(ERRNO_CODES[e.code]); 2408 } 2409 return res; 2410 },llseek:function (stream, offset, whence) { 2411 var position = offset; 2412 if (whence === 1) { // SEEK_CUR. 2413 position += stream.position; 2414 } else if (whence === 2) { // SEEK_END. 2415 if (FS.isFile(stream.node.mode)) { 2416 try { 2417 var stat = fs.fstatSync(stream.nfd); 2418 position += stat.size; 2419 } catch (e) { 2420 throw new FS.ErrnoError(ERRNO_CODES[e.code]); 2421 } 2422 } 2423 } 2424 2425 if (position < 0) { 2426 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 2427 } 2428 2429 stream.position = position; 2430 return position; 2431 }}}; 2432 2433 var _stdin=allocate(1, "i32*", ALLOC_STATIC); 2434 2435 var _stdout=allocate(1, "i32*", ALLOC_STATIC); 2436 2437 var _stderr=allocate(1, "i32*", ALLOC_STATIC); 2438 2439 function _fflush(stream) { 2440 // int fflush(FILE *stream); 2441 // http://pubs.opengroup.org/onlinepubs/000095399/functions/fflush.html 2442 // we don't currently perform any user-space buffering of data 2443 }var FS={root:null,mounts:[],devices:[null],streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},handleFSError:function (e) { 2444 if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace(); 2445 return ___setErrNo(e.errno); 2446 },lookupPath:function (path, opts) { 2447 path = PATH.resolve(FS.cwd(), path); 2448 opts = opts || {}; 2449 2450 var defaults = { 2451 follow_mount: true, 2452 recurse_count: 0 2453 }; 2454 for (var key in defaults) { 2455 if (opts[key] === undefined) { 2456 opts[key] = defaults[key]; 2457 } 2458 } 2459 2460 if (opts.recurse_count > 8) { // max recursive lookup of 8 2461 throw new FS.ErrnoError(ERRNO_CODES.ELOOP); 2462 } 2463 2464 // split the path 2465 var parts = PATH.normalizeArray(path.split('/').filter(function(p) { 2466 return !!p; 2467 }), false); 2468 2469 // start at the root 2470 var current = FS.root; 2471 var current_path = '/'; 2472 2473 for (var i = 0; i < parts.length; i++) { 2474 var islast = (i === parts.length-1); 2475 if (islast && opts.parent) { 2476 // stop resolving 2477 break; 2478 } 2479 2480 current = FS.lookupNode(current, parts[i]); 2481 current_path = PATH.join2(current_path, parts[i]); 2482 2483 // jump to the mount's root node if this is a mountpoint 2484 if (FS.isMountpoint(current)) { 2485 if (!islast || (islast && opts.follow_mount)) { 2486 current = current.mounted.root; 2487 } 2488 } 2489 2490 // by default, lookupPath will not follow a symlink if it is the final path component. 2491 // setting opts.follow = true will override this behavior. 2492 if (!islast || opts.follow) { 2493 var count = 0; 2494 while (FS.isLink(current.mode)) { 2495 var link = FS.readlink(current_path); 2496 current_path = PATH.resolve(PATH.dirname(current_path), link); 2497 2498 var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count }); 2499 current = lookup.node; 2500 2501 if (count++ > 40) { // limit max consecutive symlinks to 40 (SYMLOOP_MAX). 2502 throw new FS.ErrnoError(ERRNO_CODES.ELOOP); 2503 } 2504 } 2505 } 2506 } 2507 2508 return { path: current_path, node: current }; 2509 },getPath:function (node) { 2510 var path; 2511 while (true) { 2512 if (FS.isRoot(node)) { 2513 var mount = node.mount.mountpoint; 2514 if (!path) return mount; 2515 return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path; 2516 } 2517 path = path ? node.name + '/' + path : node.name; 2518 node = node.parent; 2519 } 2520 },hashName:function (parentid, name) { 2521 var hash = 0; 2522 2523 2524 for (var i = 0; i < name.length; i++) { 2525 hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0; 2526 } 2527 return ((parentid + hash) >>> 0) % FS.nameTable.length; 2528 },hashAddNode:function (node) { 2529 var hash = FS.hashName(node.parent.id, node.name); 2530 node.name_next = FS.nameTable[hash]; 2531 FS.nameTable[hash] = node; 2532 },hashRemoveNode:function (node) { 2533 var hash = FS.hashName(node.parent.id, node.name); 2534 if (FS.nameTable[hash] === node) { 2535 FS.nameTable[hash] = node.name_next; 2536 } else { 2537 var current = FS.nameTable[hash]; 2538 while (current) { 2539 if (current.name_next === node) { 2540 current.name_next = node.name_next; 2541 break; 2542 } 2543 current = current.name_next; 2544 } 2545 } 2546 },lookupNode:function (parent, name) { 2547 var err = FS.mayLookup(parent); 2548 if (err) { 2549 throw new FS.ErrnoError(err); 2550 } 2551 var hash = FS.hashName(parent.id, name); 2552 for (var node = FS.nameTable[hash]; node; node = node.name_next) { 2553 var nodeName = node.name; 2554 if (node.parent.id === parent.id && nodeName === name) { 2555 return node; 2556 } 2557 } 2558 // if we failed to find it in the cache, call into the VFS 2559 return FS.lookup(parent, name); 2560 },createNode:function (parent, name, mode, rdev) { 2561 if (!FS.FSNode) { 2562 FS.FSNode = function(parent, name, mode, rdev) { 2563 if (!parent) { 2564 parent = this; // root node sets parent to itself 2565 } 2566 this.parent = parent; 2567 this.mount = parent.mount; 2568 this.mounted = null; 2569 this.id = FS.nextInode++; 2570 this.name = name; 2571 this.mode = mode; 2572 this.node_ops = {}; 2573 this.stream_ops = {}; 2574 this.rdev = rdev; 2575 }; 2576 2577 FS.FSNode.prototype = {}; 2578 2579 // compatibility 2580 var readMode = 292 | 73; 2581 var writeMode = 146; 2582 2583 // NOTE we must use Object.defineProperties instead of individual calls to 2584 // Object.defineProperty in order to make closure compiler happy 2585 Object.defineProperties(FS.FSNode.prototype, { 2586 read: { 2587 get: function() { return (this.mode & readMode) === readMode; }, 2588 set: function(val) { val ? this.mode |= readMode : this.mode &= ~readMode; } 2589 }, 2590 write: { 2591 get: function() { return (this.mode & writeMode) === writeMode; }, 2592 set: function(val) { val ? this.mode |= writeMode : this.mode &= ~writeMode; } 2593 }, 2594 isFolder: { 2595 get: function() { return FS.isDir(this.mode); }, 2596 }, 2597 isDevice: { 2598 get: function() { return FS.isChrdev(this.mode); }, 2599 }, 2600 }); 2601 } 2602 2603 var node = new FS.FSNode(parent, name, mode, rdev); 2604 2605 FS.hashAddNode(node); 2606 2607 return node; 2608 },destroyNode:function (node) { 2609 FS.hashRemoveNode(node); 2610 },isRoot:function (node) { 2611 return node === node.parent; 2612 },isMountpoint:function (node) { 2613 return !!node.mounted; 2614 },isFile:function (mode) { 2615 return (mode & 61440) === 32768; 2616 },isDir:function (mode) { 2617 return (mode & 61440) === 16384; 2618 },isLink:function (mode) { 2619 return (mode & 61440) === 40960; 2620 },isChrdev:function (mode) { 2621 return (mode & 61440) === 8192; 2622 },isBlkdev:function (mode) { 2623 return (mode & 61440) === 24576; 2624 },isFIFO:function (mode) { 2625 return (mode & 61440) === 4096; 2626 },isSocket:function (mode) { 2627 return (mode & 49152) === 49152; 2628 },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) { 2629 var flags = FS.flagModes[str]; 2630 if (typeof flags === 'undefined') { 2631 throw new Error('Unknown file open mode: ' + str); 2632 } 2633 return flags; 2634 },flagsToPermissionString:function (flag) { 2635 var accmode = flag & 2097155; 2636 var perms = ['r', 'w', 'rw'][accmode]; 2637 if ((flag & 512)) { 2638 perms += 'w'; 2639 } 2640 return perms; 2641 },nodePermissions:function (node, perms) { 2642 if (FS.ignorePermissions) { 2643 return 0; 2644 } 2645 // return 0 if any user, group or owner bits are set. 2646 if (perms.indexOf('r') !== -1 && !(node.mode & 292)) { 2647 return ERRNO_CODES.EACCES; 2648 } else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) { 2649 return ERRNO_CODES.EACCES; 2650 } else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) { 2651 return ERRNO_CODES.EACCES; 2652 } 2653 return 0; 2654 },mayLookup:function (dir) { 2655 return FS.nodePermissions(dir, 'x'); 2656 },mayCreate:function (dir, name) { 2657 try { 2658 var node = FS.lookupNode(dir, name); 2659 return ERRNO_CODES.EEXIST; 2660 } catch (e) { 2661 } 2662 return FS.nodePermissions(dir, 'wx'); 2663 },mayDelete:function (dir, name, isdir) { 2664 var node; 2665 try { 2666 node = FS.lookupNode(dir, name); 2667 } catch (e) { 2668 return e.errno; 2669 } 2670 var err = FS.nodePermissions(dir, 'wx'); 2671 if (err) { 2672 return err; 2673 } 2674 if (isdir) { 2675 if (!FS.isDir(node.mode)) { 2676 return ERRNO_CODES.ENOTDIR; 2677 } 2678 if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) { 2679 return ERRNO_CODES.EBUSY; 2680 } 2681 } else { 2682 if (FS.isDir(node.mode)) { 2683 return ERRNO_CODES.EISDIR; 2684 } 2685 } 2686 return 0; 2687 },mayOpen:function (node, flags) { 2688 if (!node) { 2689 return ERRNO_CODES.ENOENT; 2690 } 2691 if (FS.isLink(node.mode)) { 2692 return ERRNO_CODES.ELOOP; 2693 } else if (FS.isDir(node.mode)) { 2694 if ((flags & 2097155) !== 0 || // opening for write 2695 (flags & 512)) { 2696 return ERRNO_CODES.EISDIR; 2697 } 2698 } 2699 return FS.nodePermissions(node, FS.flagsToPermissionString(flags)); 2700 },MAX_OPEN_FDS:4096,nextfd:function (fd_start, fd_end) { 2701 fd_start = fd_start || 0; 2702 fd_end = fd_end || FS.MAX_OPEN_FDS; 2703 for (var fd = fd_start; fd <= fd_end; fd++) { 2704 if (!FS.streams[fd]) { 2705 return fd; 2706 } 2707 } 2708 throw new FS.ErrnoError(ERRNO_CODES.EMFILE); 2709 },getStream:function (fd) { 2710 return FS.streams[fd]; 2711 },createStream:function (stream, fd_start, fd_end) { 2712 if (!FS.FSStream) { 2713 FS.FSStream = function(){}; 2714 FS.FSStream.prototype = {}; 2715 // compatibility 2716 Object.defineProperties(FS.FSStream.prototype, { 2717 object: { 2718 get: function() { return this.node; }, 2719 set: function(val) { this.node = val; } 2720 }, 2721 isRead: { 2722 get: function() { return (this.flags & 2097155) !== 1; } 2723 }, 2724 isWrite: { 2725 get: function() { return (this.flags & 2097155) !== 0; } 2726 }, 2727 isAppend: { 2728 get: function() { return (this.flags & 1024); } 2729 } 2730 }); 2731 } 2732 if (0) { 2733 // reuse the object 2734 stream.__proto__ = FS.FSStream.prototype; 2735 } else { 2736 var newStream = new FS.FSStream(); 2737 for (var p in stream) { 2738 newStream[p] = stream[p]; 2739 } 2740 stream = newStream; 2741 } 2742 var fd = FS.nextfd(fd_start, fd_end); 2743 stream.fd = fd; 2744 FS.streams[fd] = stream; 2745 return stream; 2746 },closeStream:function (fd) { 2747 FS.streams[fd] = null; 2748 },getStreamFromPtr:function (ptr) { 2749 return FS.streams[ptr - 1]; 2750 },getPtrForStream:function (stream) { 2751 return stream ? stream.fd + 1 : 0; 2752 },chrdev_stream_ops:{open:function (stream) { 2753 var device = FS.getDevice(stream.node.rdev); 2754 // override node's stream ops with the device's 2755 stream.stream_ops = device.stream_ops; 2756 // forward the open call 2757 if (stream.stream_ops.open) { 2758 stream.stream_ops.open(stream); 2759 } 2760 },llseek:function () { 2761 throw new FS.ErrnoError(ERRNO_CODES.ESPIPE); 2762 }},major:function (dev) { 2763 return ((dev) >> 8); 2764 },minor:function (dev) { 2765 return ((dev) & 0xff); 2766 },makedev:function (ma, mi) { 2767 return ((ma) << 8 | (mi)); 2768 },registerDevice:function (dev, ops) { 2769 FS.devices[dev] = { stream_ops: ops }; 2770 },getDevice:function (dev) { 2771 return FS.devices[dev]; 2772 },getMounts:function (mount) { 2773 var mounts = []; 2774 var check = [mount]; 2775 2776 while (check.length) { 2777 var m = check.pop(); 2778 2779 mounts.push(m); 2780 2781 check.push.apply(check, m.mounts); 2782 } 2783 2784 return mounts; 2785 },syncfs:function (populate, callback) { 2786 if (typeof(populate) === 'function') { 2787 callback = populate; 2788 populate = false; 2789 } 2790 2791 var mounts = FS.getMounts(FS.root.mount); 2792 var completed = 0; 2793 2794 function done(err) { 2795 if (err) { 2796 if (!done.errored) { 2797 done.errored = true; 2798 return callback(err); 2799 } 2800 return; 2801 } 2802 if (++completed >= mounts.length) { 2803 callback(null); 2804 } 2805 }; 2806 2807 // sync all mounts 2808 mounts.forEach(function (mount) { 2809 if (!mount.type.syncfs) { 2810 return done(null); 2811 } 2812 mount.type.syncfs(mount, populate, done); 2813 }); 2814 },mount:function (type, opts, mountpoint) { 2815 var root = mountpoint === '/'; 2816 var pseudo = !mountpoint; 2817 var node; 2818 2819 if (root && FS.root) { 2820 throw new FS.ErrnoError(ERRNO_CODES.EBUSY); 2821 } else if (!root && !pseudo) { 2822 var lookup = FS.lookupPath(mountpoint, { follow_mount: false }); 2823 2824 mountpoint = lookup.path; // use the absolute path 2825 node = lookup.node; 2826 2827 if (FS.isMountpoint(node)) { 2828 throw new FS.ErrnoError(ERRNO_CODES.EBUSY); 2829 } 2830 2831 if (!FS.isDir(node.mode)) { 2832 throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR); 2833 } 2834 } 2835 2836 var mount = { 2837 type: type, 2838 opts: opts, 2839 mountpoint: mountpoint, 2840 mounts: [] 2841 }; 2842 2843 // create a root node for the fs 2844 var mountRoot = type.mount(mount); 2845 mountRoot.mount = mount; 2846 mount.root = mountRoot; 2847 2848 if (root) { 2849 FS.root = mountRoot; 2850 } else if (node) { 2851 // set as a mountpoint 2852 node.mounted = mount; 2853 2854 // add the new mount to the current mount's children 2855 if (node.mount) { 2856 node.mount.mounts.push(mount); 2857 } 2858 } 2859 2860 return mountRoot; 2861 },unmount:function (mountpoint) { 2862 var lookup = FS.lookupPath(mountpoint, { follow_mount: false }); 2863 2864 if (!FS.isMountpoint(lookup.node)) { 2865 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 2866 } 2867 2868 // destroy the nodes for this mount, and all its child mounts 2869 var node = lookup.node; 2870 var mount = node.mounted; 2871 var mounts = FS.getMounts(mount); 2872 2873 Object.keys(FS.nameTable).forEach(function (hash) { 2874 var current = FS.nameTable[hash]; 2875 2876 while (current) { 2877 var next = current.name_next; 2878 2879 if (mounts.indexOf(current.mount) !== -1) { 2880 FS.destroyNode(current); 2881 } 2882 2883 current = next; 2884 } 2885 }); 2886 2887 // no longer a mountpoint 2888 node.mounted = null; 2889 2890 // remove this mount from the child mounts 2891 var idx = node.mount.mounts.indexOf(mount); 2892 assert(idx !== -1); 2893 node.mount.mounts.splice(idx, 1); 2894 },lookup:function (parent, name) { 2895 return parent.node_ops.lookup(parent, name); 2896 },mknod:function (path, mode, dev) { 2897 var lookup = FS.lookupPath(path, { parent: true }); 2898 var parent = lookup.node; 2899 var name = PATH.basename(path); 2900 var err = FS.mayCreate(parent, name); 2901 if (err) { 2902 throw new FS.ErrnoError(err); 2903 } 2904 if (!parent.node_ops.mknod) { 2905 throw new FS.ErrnoError(ERRNO_CODES.EPERM); 2906 } 2907 return parent.node_ops.mknod(parent, name, mode, dev); 2908 },create:function (path, mode) { 2909 mode = mode !== undefined ? mode : 438 /* 0666 */; 2910 mode &= 4095; 2911 mode |= 32768; 2912 return FS.mknod(path, mode, 0); 2913 },mkdir:function (path, mode) { 2914 mode = mode !== undefined ? mode : 511 /* 0777 */; 2915 mode &= 511 | 512; 2916 mode |= 16384; 2917 return FS.mknod(path, mode, 0); 2918 },mkdev:function (path, mode, dev) { 2919 if (typeof(dev) === 'undefined') { 2920 dev = mode; 2921 mode = 438 /* 0666 */; 2922 } 2923 mode |= 8192; 2924 return FS.mknod(path, mode, dev); 2925 },symlink:function (oldpath, newpath) { 2926 var lookup = FS.lookupPath(newpath, { parent: true }); 2927 var parent = lookup.node; 2928 var newname = PATH.basename(newpath); 2929 var err = FS.mayCreate(parent, newname); 2930 if (err) { 2931 throw new FS.ErrnoError(err); 2932 } 2933 if (!parent.node_ops.symlink) { 2934 throw new FS.ErrnoError(ERRNO_CODES.EPERM); 2935 } 2936 return parent.node_ops.symlink(parent, newname, oldpath); 2937 },rename:function (old_path, new_path) { 2938 var old_dirname = PATH.dirname(old_path); 2939 var new_dirname = PATH.dirname(new_path); 2940 var old_name = PATH.basename(old_path); 2941 var new_name = PATH.basename(new_path); 2942 // parents must exist 2943 var lookup, old_dir, new_dir; 2944 try { 2945 lookup = FS.lookupPath(old_path, { parent: true }); 2946 old_dir = lookup.node; 2947 lookup = FS.lookupPath(new_path, { parent: true }); 2948 new_dir = lookup.node; 2949 } catch (e) { 2950 throw new FS.ErrnoError(ERRNO_CODES.EBUSY); 2951 } 2952 // need to be part of the same mount 2953 if (old_dir.mount !== new_dir.mount) { 2954 throw new FS.ErrnoError(ERRNO_CODES.EXDEV); 2955 } 2956 // source must exist 2957 var old_node = FS.lookupNode(old_dir, old_name); 2958 // old path should not be an ancestor of the new path 2959 var relative = PATH.relative(old_path, new_dirname); 2960 if (relative.charAt(0) !== '.') { 2961 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 2962 } 2963 // new path should not be an ancestor of the old path 2964 relative = PATH.relative(new_path, old_dirname); 2965 if (relative.charAt(0) !== '.') { 2966 throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY); 2967 } 2968 // see if the new path already exists 2969 var new_node; 2970 try { 2971 new_node = FS.lookupNode(new_dir, new_name); 2972 } catch (e) { 2973 // not fatal 2974 } 2975 // early out if nothing needs to change 2976 if (old_node === new_node) { 2977 return; 2978 } 2979 // we'll need to delete the old entry 2980 var isdir = FS.isDir(old_node.mode); 2981 var err = FS.mayDelete(old_dir, old_name, isdir); 2982 if (err) { 2983 throw new FS.ErrnoError(err); 2984 } 2985 // need delete permissions if we'll be overwriting. 2986 // need create permissions if new doesn't already exist. 2987 err = new_node ? 2988 FS.mayDelete(new_dir, new_name, isdir) : 2989 FS.mayCreate(new_dir, new_name); 2990 if (err) { 2991 throw new FS.ErrnoError(err); 2992 } 2993 if (!old_dir.node_ops.rename) { 2994 throw new FS.ErrnoError(ERRNO_CODES.EPERM); 2995 } 2996 if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) { 2997 throw new FS.ErrnoError(ERRNO_CODES.EBUSY); 2998 } 2999 // if we are going to change the parent, check write permissions 3000 if (new_dir !== old_dir) { 3001 err = FS.nodePermissions(old_dir, 'w'); 3002 if (err) { 3003 throw new FS.ErrnoError(err); 3004 } 3005 } 3006 // remove the node from the lookup hash 3007 FS.hashRemoveNode(old_node); 3008 // do the underlying fs rename 3009 try { 3010 old_dir.node_ops.rename(old_node, new_dir, new_name); 3011 } catch (e) { 3012 throw e; 3013 } finally { 3014 // add the node back to the hash (in case node_ops.rename 3015 // changed its name) 3016 FS.hashAddNode(old_node); 3017 } 3018 },rmdir:function (path) { 3019 var lookup = FS.lookupPath(path, { parent: true }); 3020 var parent = lookup.node; 3021 var name = PATH.basename(path); 3022 var node = FS.lookupNode(parent, name); 3023 var err = FS.mayDelete(parent, name, true); 3024 if (err) { 3025 throw new FS.ErrnoError(err); 3026 } 3027 if (!parent.node_ops.rmdir) { 3028 throw new FS.ErrnoError(ERRNO_CODES.EPERM); 3029 } 3030 if (FS.isMountpoint(node)) { 3031 throw new FS.ErrnoError(ERRNO_CODES.EBUSY); 3032 } 3033 parent.node_ops.rmdir(parent, name); 3034 FS.destroyNode(node); 3035 },readdir:function (path) { 3036 var lookup = FS.lookupPath(path, { follow: true }); 3037 var node = lookup.node; 3038 if (!node.node_ops.readdir) { 3039 throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR); 3040 } 3041 return node.node_ops.readdir(node); 3042 },unlink:function (path) { 3043 var lookup = FS.lookupPath(path, { parent: true }); 3044 var parent = lookup.node; 3045 var name = PATH.basename(path); 3046 var node = FS.lookupNode(parent, name); 3047 var err = FS.mayDelete(parent, name, false); 3048 if (err) { 3049 // POSIX says unlink should set EPERM, not EISDIR 3050 if (err === ERRNO_CODES.EISDIR) err = ERRNO_CODES.EPERM; 3051 throw new FS.ErrnoError(err); 3052 } 3053 if (!parent.node_ops.unlink) { 3054 throw new FS.ErrnoError(ERRNO_CODES.EPERM); 3055 } 3056 if (FS.isMountpoint(node)) { 3057 throw new FS.ErrnoError(ERRNO_CODES.EBUSY); 3058 } 3059 parent.node_ops.unlink(parent, name); 3060 FS.destroyNode(node); 3061 },readlink:function (path) { 3062 var lookup = FS.lookupPath(path); 3063 var link = lookup.node; 3064 if (!link.node_ops.readlink) { 3065 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 3066 } 3067 return link.node_ops.readlink(link); 3068 },stat:function (path, dontFollow) { 3069 var lookup = FS.lookupPath(path, { follow: !dontFollow }); 3070 var node = lookup.node; 3071 if (!node.node_ops.getattr) { 3072 throw new FS.ErrnoError(ERRNO_CODES.EPERM); 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(ERRNO_CODES.EPERM); 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(ERRNO_CODES.EBADF); 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(ERRNO_CODES.EPERM); 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(ERRNO_CODES.EBADF); 3121 } 3122 FS.chown(stream.node, uid, gid); 3123 },truncate:function (path, len) { 3124 if (len < 0) { 3125 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 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(ERRNO_CODES.EPERM); 3136 } 3137 if (FS.isDir(node.mode)) { 3138 throw new FS.ErrnoError(ERRNO_CODES.EISDIR); 3139 } 3140 if (!FS.isFile(node.mode)) { 3141 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 3142 } 3143 var err = FS.nodePermissions(node, 'w'); 3144 if (err) { 3145 throw new FS.ErrnoError(err); 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(ERRNO_CODES.EBADF); 3155 } 3156 if ((stream.flags & 2097155) === 0) { 3157 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 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 flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags; 3168 mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode; 3169 if ((flags & 64)) { 3170 mode = (mode & 4095) | 32768; 3171 } else { 3172 mode = 0; 3173 } 3174 var node; 3175 if (typeof path === 'object') { 3176 node = path; 3177 } else { 3178 path = PATH.normalize(path); 3179 try { 3180 var lookup = FS.lookupPath(path, { 3181 follow: !(flags & 131072) 3182 }); 3183 node = lookup.node; 3184 } catch (e) { 3185 // ignore 3186 } 3187 } 3188 // perhaps we need to create the node 3189 if ((flags & 64)) { 3190 if (node) { 3191 // if O_CREAT and O_EXCL are set, error out if the node already exists 3192 if ((flags & 128)) { 3193 throw new FS.ErrnoError(ERRNO_CODES.EEXIST); 3194 } 3195 } else { 3196 // node doesn't exist, try to create it 3197 node = FS.mknod(path, mode, 0); 3198 } 3199 } 3200 if (!node) { 3201 throw new FS.ErrnoError(ERRNO_CODES.ENOENT); 3202 } 3203 // can't truncate a device 3204 if (FS.isChrdev(node.mode)) { 3205 flags &= ~512; 3206 } 3207 // check permissions 3208 var err = FS.mayOpen(node, flags); 3209 if (err) { 3210 throw new FS.ErrnoError(err); 3211 } 3212 // do truncation if necessary 3213 if ((flags & 512)) { 3214 FS.truncate(node, 0); 3215 } 3216 // we've already handled these, don't pass down to the underlying vfs 3217 flags &= ~(128 | 512); 3218 3219 // register the stream with the filesystem 3220 var stream = FS.createStream({ 3221 node: node, 3222 path: FS.getPath(node), // we want the absolute path to the node 3223 flags: flags, 3224 seekable: true, 3225 position: 0, 3226 stream_ops: node.stream_ops, 3227 // used by the file family libc calls (fopen, fwrite, ferror, etc.) 3228 ungotten: [], 3229 error: false 3230 }, fd_start, fd_end); 3231 // call the new stream's open function 3232 if (stream.stream_ops.open) { 3233 stream.stream_ops.open(stream); 3234 } 3235 if (Module['logReadFiles'] && !(flags & 1)) { 3236 if (!FS.readFiles) FS.readFiles = {}; 3237 if (!(path in FS.readFiles)) { 3238 FS.readFiles[path] = 1; 3239 Module['printErr']('read file: ' + path); 3240 } 3241 } 3242 return stream; 3243 },close:function (stream) { 3244 try { 3245 if (stream.stream_ops.close) { 3246 stream.stream_ops.close(stream); 3247 } 3248 } catch (e) { 3249 throw e; 3250 } finally { 3251 FS.closeStream(stream.fd); 3252 } 3253 },llseek:function (stream, offset, whence) { 3254 if (!stream.seekable || !stream.stream_ops.llseek) { 3255 throw new FS.ErrnoError(ERRNO_CODES.ESPIPE); 3256 } 3257 return stream.stream_ops.llseek(stream, offset, whence); 3258 },read:function (stream, buffer, offset, length, position) { 3259 if (length < 0 || position < 0) { 3260 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 3261 } 3262 if ((stream.flags & 2097155) === 1) { 3263 throw new FS.ErrnoError(ERRNO_CODES.EBADF); 3264 } 3265 if (FS.isDir(stream.node.mode)) { 3266 throw new FS.ErrnoError(ERRNO_CODES.EISDIR); 3267 } 3268 if (!stream.stream_ops.read) { 3269 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 3270 } 3271 var seeking = true; 3272 if (typeof position === 'undefined') { 3273 position = stream.position; 3274 seeking = false; 3275 } else if (!stream.seekable) { 3276 throw new FS.ErrnoError(ERRNO_CODES.ESPIPE); 3277 } 3278 var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position); 3279 if (!seeking) stream.position += bytesRead; 3280 return bytesRead; 3281 },write:function (stream, buffer, offset, length, position, canOwn) { 3282 if (length < 0 || position < 0) { 3283 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 3284 } 3285 if ((stream.flags & 2097155) === 0) { 3286 throw new FS.ErrnoError(ERRNO_CODES.EBADF); 3287 } 3288 if (FS.isDir(stream.node.mode)) { 3289 throw new FS.ErrnoError(ERRNO_CODES.EISDIR); 3290 } 3291 if (!stream.stream_ops.write) { 3292 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 3293 } 3294 var seeking = true; 3295 if (typeof position === 'undefined') { 3296 position = stream.position; 3297 seeking = false; 3298 } else if (!stream.seekable) { 3299 throw new FS.ErrnoError(ERRNO_CODES.ESPIPE); 3300 } 3301 if (stream.flags & 1024) { 3302 // seek to the end before writing in append mode 3303 FS.llseek(stream, 0, 2); 3304 } 3305 var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn); 3306 if (!seeking) stream.position += bytesWritten; 3307 return bytesWritten; 3308 },allocate:function (stream, offset, length) { 3309 if (offset < 0 || length <= 0) { 3310 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 3311 } 3312 if ((stream.flags & 2097155) === 0) { 3313 throw new FS.ErrnoError(ERRNO_CODES.EBADF); 3314 } 3315 if (!FS.isFile(stream.node.mode) && !FS.isDir(node.mode)) { 3316 throw new FS.ErrnoError(ERRNO_CODES.ENODEV); 3317 } 3318 if (!stream.stream_ops.allocate) { 3319 throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP); 3320 } 3321 stream.stream_ops.allocate(stream, offset, length); 3322 },mmap:function (stream, buffer, offset, length, position, prot, flags) { 3323 // TODO if PROT is PROT_WRITE, make sure we have write access 3324 if ((stream.flags & 2097155) === 1) { 3325 throw new FS.ErrnoError(ERRNO_CODES.EACCES); 3326 } 3327 if (!stream.stream_ops.mmap) { 3328 throw new FS.ErrnoError(ERRNO_CODES.ENODEV); 3329 } 3330 return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags); 3331 },ioctl:function (stream, cmd, arg) { 3332 if (!stream.stream_ops.ioctl) { 3333 throw new FS.ErrnoError(ERRNO_CODES.ENOTTY); 3334 } 3335 return stream.stream_ops.ioctl(stream, cmd, arg); 3336 },readFile:function (path, opts) { 3337 opts = opts || {}; 3338 opts.flags = opts.flags || 'r'; 3339 opts.encoding = opts.encoding || 'binary'; 3340 if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') { 3341 throw new Error('Invalid encoding type "' + opts.encoding + '"'); 3342 } 3343 var ret; 3344 var stream = FS.open(path, opts.flags); 3345 var stat = FS.stat(path); 3346 var length = stat.size; 3347 var buf = new Uint8Array(length); 3348 FS.read(stream, buf, 0, length, 0); 3349 if (opts.encoding === 'utf8') { 3350 ret = ''; 3351 var utf8 = new Runtime.UTF8Processor(); 3352 for (var i = 0; i < length; i++) { 3353 ret += utf8.processCChar(buf[i]); 3354 } 3355 } else if (opts.encoding === 'binary') { 3356 ret = buf; 3357 } 3358 FS.close(stream); 3359 return ret; 3360 },writeFile:function (path, data, opts) { 3361 opts = opts || {}; 3362 opts.flags = opts.flags || 'w'; 3363 opts.encoding = opts.encoding || 'utf8'; 3364 if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') { 3365 throw new Error('Invalid encoding type "' + opts.encoding + '"'); 3366 } 3367 var stream = FS.open(path, opts.flags, opts.mode); 3368 if (opts.encoding === 'utf8') { 3369 var utf8 = new Runtime.UTF8Processor(); 3370 var buf = new Uint8Array(utf8.processJSString(data)); 3371 FS.write(stream, buf, 0, buf.length, 0, opts.canOwn); 3372 } else if (opts.encoding === 'binary') { 3373 FS.write(stream, data, 0, data.length, 0, opts.canOwn); 3374 } 3375 FS.close(stream); 3376 },cwd:function () { 3377 return FS.currentPath; 3378 },chdir:function (path) { 3379 var lookup = FS.lookupPath(path, { follow: true }); 3380 if (!FS.isDir(lookup.node.mode)) { 3381 throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR); 3382 } 3383 var err = FS.nodePermissions(lookup.node, 'x'); 3384 if (err) { 3385 throw new FS.ErrnoError(err); 3386 } 3387 FS.currentPath = lookup.path; 3388 },createDefaultDirectories:function () { 3389 FS.mkdir('/tmp'); 3390 },createDefaultDevices:function () { 3391 // create /dev 3392 FS.mkdir('/dev'); 3393 // setup /dev/null 3394 FS.registerDevice(FS.makedev(1, 3), { 3395 read: function() { return 0; }, 3396 write: function() { return 0; } 3397 }); 3398 FS.mkdev('/dev/null', FS.makedev(1, 3)); 3399 // setup /dev/tty and /dev/tty1 3400 // stderr needs to print output using Module['printErr'] 3401 // so we register a second tty just for it. 3402 TTY.register(FS.makedev(5, 0), TTY.default_tty_ops); 3403 TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops); 3404 FS.mkdev('/dev/tty', FS.makedev(5, 0)); 3405 FS.mkdev('/dev/tty1', FS.makedev(6, 0)); 3406 // we're not going to emulate the actual shm device, 3407 // just create the tmp dirs that reside in it commonly 3408 FS.mkdir('/dev/shm'); 3409 FS.mkdir('/dev/shm/tmp'); 3410 },createStandardStreams:function () { 3411 // TODO deprecate the old functionality of a single 3412 // input / output callback and that utilizes FS.createDevice 3413 // and instead require a unique set of stream ops 3414 3415 // by default, we symlink the standard streams to the 3416 // default tty devices. however, if the standard streams 3417 // have been overwritten we create a unique device for 3418 // them instead. 3419 if (Module['stdin']) { 3420 FS.createDevice('/dev', 'stdin', Module['stdin']); 3421 } else { 3422 FS.symlink('/dev/tty', '/dev/stdin'); 3423 } 3424 if (Module['stdout']) { 3425 FS.createDevice('/dev', 'stdout', null, Module['stdout']); 3426 } else { 3427 FS.symlink('/dev/tty', '/dev/stdout'); 3428 } 3429 if (Module['stderr']) { 3430 FS.createDevice('/dev', 'stderr', null, Module['stderr']); 3431 } else { 3432 FS.symlink('/dev/tty1', '/dev/stderr'); 3433 } 3434 3435 // open default streams for the stdin, stdout and stderr devices 3436 var stdin = FS.open('/dev/stdin', 'r'); 3437 HEAP32[((_stdin)>>2)]=FS.getPtrForStream(stdin); 3438 assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')'); 3439 3440 var stdout = FS.open('/dev/stdout', 'w'); 3441 HEAP32[((_stdout)>>2)]=FS.getPtrForStream(stdout); 3442 assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')'); 3443 3444 var stderr = FS.open('/dev/stderr', 'w'); 3445 HEAP32[((_stderr)>>2)]=FS.getPtrForStream(stderr); 3446 assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')'); 3447 },ensureErrnoError:function () { 3448 if (FS.ErrnoError) return; 3449 FS.ErrnoError = function ErrnoError(errno) { 3450 this.errno = errno; 3451 for (var key in ERRNO_CODES) { 3452 if (ERRNO_CODES[key] === errno) { 3453 this.code = key; 3454 break; 3455 } 3456 } 3457 this.message = ERRNO_MESSAGES[errno]; 3458 }; 3459 FS.ErrnoError.prototype = new Error(); 3460 FS.ErrnoError.prototype.constructor = FS.ErrnoError; 3461 // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info) 3462 [ERRNO_CODES.ENOENT].forEach(function(code) { 3463 FS.genericErrors[code] = new FS.ErrnoError(code); 3464 FS.genericErrors[code].stack = '<generic error, no stack>'; 3465 }); 3466 },staticInit:function () { 3467 FS.ensureErrnoError(); 3468 3469 FS.nameTable = new Array(4096); 3470 3471 FS.mount(MEMFS, {}, '/'); 3472 3473 FS.createDefaultDirectories(); 3474 FS.createDefaultDevices(); 3475 },init:function (input, output, error) { 3476 assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)'); 3477 FS.init.initialized = true; 3478 3479 FS.ensureErrnoError(); 3480 3481 // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here 3482 Module['stdin'] = input || Module['stdin']; 3483 Module['stdout'] = output || Module['stdout']; 3484 Module['stderr'] = error || Module['stderr']; 3485 3486 FS.createStandardStreams(); 3487 },quit:function () { 3488 FS.init.initialized = false; 3489 for (var i = 0; i < FS.streams.length; i++) { 3490 var stream = FS.streams[i]; 3491 if (!stream) { 3492 continue; 3493 } 3494 FS.close(stream); 3495 } 3496 },getMode:function (canRead, canWrite) { 3497 var mode = 0; 3498 if (canRead) mode |= 292 | 73; 3499 if (canWrite) mode |= 146; 3500 return mode; 3501 },joinPath:function (parts, forceRelative) { 3502 var path = PATH.join.apply(null, parts); 3503 if (forceRelative && path[0] == '/') path = path.substr(1); 3504 return path; 3505 },absolutePath:function (relative, base) { 3506 return PATH.resolve(base, relative); 3507 },standardizePath:function (path) { 3508 return PATH.normalize(path); 3509 },findObject:function (path, dontResolveLastLink) { 3510 var ret = FS.analyzePath(path, dontResolveLastLink); 3511 if (ret.exists) { 3512 return ret.object; 3513 } else { 3514 ___setErrNo(ret.error); 3515 return null; 3516 } 3517 },analyzePath:function (path, dontResolveLastLink) { 3518 // operate from within the context of the symlink's target 3519 try { 3520 var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink }); 3521 path = lookup.path; 3522 } catch (e) { 3523 } 3524 var ret = { 3525 isRoot: false, exists: false, error: 0, name: null, path: null, object: null, 3526 parentExists: false, parentPath: null, parentObject: null 3527 }; 3528 try { 3529 var lookup = FS.lookupPath(path, { parent: true }); 3530 ret.parentExists = true; 3531 ret.parentPath = lookup.path; 3532 ret.parentObject = lookup.node; 3533 ret.name = PATH.basename(path); 3534 lookup = FS.lookupPath(path, { follow: !dontResolveLastLink }); 3535 ret.exists = true; 3536 ret.path = lookup.path; 3537 ret.object = lookup.node; 3538 ret.name = lookup.node.name; 3539 ret.isRoot = lookup.path === '/'; 3540 } catch (e) { 3541 ret.error = e.errno; 3542 }; 3543 return ret; 3544 },createFolder:function (parent, name, canRead, canWrite) { 3545 var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name); 3546 var mode = FS.getMode(canRead, canWrite); 3547 return FS.mkdir(path, mode); 3548 },createPath:function (parent, path, canRead, canWrite) { 3549 parent = typeof parent === 'string' ? parent : FS.getPath(parent); 3550 var parts = path.split('/').reverse(); 3551 while (parts.length) { 3552 var part = parts.pop(); 3553 if (!part) continue; 3554 var current = PATH.join2(parent, part); 3555 try { 3556 FS.mkdir(current); 3557 } catch (e) { 3558 // ignore EEXIST 3559 } 3560 parent = current; 3561 } 3562 return current; 3563 },createFile:function (parent, name, properties, canRead, canWrite) { 3564 var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name); 3565 var mode = FS.getMode(canRead, canWrite); 3566 return FS.create(path, mode); 3567 },createDataFile:function (parent, name, data, canRead, canWrite, canOwn) { 3568 var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent; 3569 var mode = FS.getMode(canRead, canWrite); 3570 var node = FS.create(path, mode); 3571 if (data) { 3572 if (typeof data === 'string') { 3573 var arr = new Array(data.length); 3574 for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i); 3575 data = arr; 3576 } 3577 // make sure we can write to the file 3578 FS.chmod(node, mode | 146); 3579 var stream = FS.open(node, 'w'); 3580 FS.write(stream, data, 0, data.length, 0, canOwn); 3581 FS.close(stream); 3582 FS.chmod(node, mode); 3583 } 3584 return node; 3585 },createDevice:function (parent, name, input, output) { 3586 var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name); 3587 var mode = FS.getMode(!!input, !!output); 3588 if (!FS.createDevice.major) FS.createDevice.major = 64; 3589 var dev = FS.makedev(FS.createDevice.major++, 0); 3590 // Create a fake device that a set of stream ops to emulate 3591 // the old behavior. 3592 FS.registerDevice(dev, { 3593 open: function(stream) { 3594 stream.seekable = false; 3595 }, 3596 close: function(stream) { 3597 // flush any pending line data 3598 if (output && output.buffer && output.buffer.length) { 3599 output(10); 3600 } 3601 }, 3602 read: function(stream, buffer, offset, length, pos /* ignored */) { 3603 var bytesRead = 0; 3604 for (var i = 0; i < length; i++) { 3605 var result; 3606 try { 3607 result = input(); 3608 } catch (e) { 3609 throw new FS.ErrnoError(ERRNO_CODES.EIO); 3610 } 3611 if (result === undefined && bytesRead === 0) { 3612 throw new FS.ErrnoError(ERRNO_CODES.EAGAIN); 3613 } 3614 if (result === null || result === undefined) break; 3615 bytesRead++; 3616 buffer[offset+i] = result; 3617 } 3618 if (bytesRead) { 3619 stream.node.timestamp = Date.now(); 3620 } 3621 return bytesRead; 3622 }, 3623 write: function(stream, buffer, offset, length, pos) { 3624 for (var i = 0; i < length; i++) { 3625 try { 3626 output(buffer[offset+i]); 3627 } catch (e) { 3628 throw new FS.ErrnoError(ERRNO_CODES.EIO); 3629 } 3630 } 3631 if (length) { 3632 stream.node.timestamp = Date.now(); 3633 } 3634 return i; 3635 } 3636 }); 3637 return FS.mkdev(path, mode, dev); 3638 },createLink:function (parent, name, target, canRead, canWrite) { 3639 var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name); 3640 return FS.symlink(target, path); 3641 },forceLoadFile:function (obj) { 3642 if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true; 3643 var success = true; 3644 if (typeof XMLHttpRequest !== 'undefined') { 3645 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."); 3646 } else if (Module['read']) { 3647 // Command-line. 3648 try { 3649 // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as 3650 // read() will try to parse UTF8. 3651 obj.contents = intArrayFromString(Module['read'](obj.url), true); 3652 } catch (e) { 3653 success = false; 3654 } 3655 } else { 3656 throw new Error('Cannot load without read() or XMLHttpRequest.'); 3657 } 3658 if (!success) ___setErrNo(ERRNO_CODES.EIO); 3659 return success; 3660 },createLazyFile:function (parent, name, url, canRead, canWrite) { 3661 // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse. 3662 function LazyUint8Array() { 3663 this.lengthKnown = false; 3664 this.chunks = []; // Loaded chunks. Index is the chunk number 3665 } 3666 LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) { 3667 if (idx > this.length-1 || idx < 0) { 3668 return undefined; 3669 } 3670 var chunkOffset = idx % this.chunkSize; 3671 var chunkNum = Math.floor(idx / this.chunkSize); 3672 return this.getter(chunkNum)[chunkOffset]; 3673 } 3674 LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) { 3675 this.getter = getter; 3676 } 3677 LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() { 3678 // Find length 3679 var xhr = new XMLHttpRequest(); 3680 xhr.open('HEAD', url, false); 3681 xhr.send(null); 3682 if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); 3683 var datalength = Number(xhr.getResponseHeader("Content-length")); 3684 var header; 3685 var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; 3686 var chunkSize = 1024*1024; // Chunk size in bytes 3687 3688 if (!hasByteServing) chunkSize = datalength; 3689 3690 // Function to get a range from the remote URL. 3691 var doXHR = (function(from, to) { 3692 if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!"); 3693 if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!"); 3694 3695 // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available. 3696 var xhr = new XMLHttpRequest(); 3697 xhr.open('GET', url, false); 3698 if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); 3699 3700 // Some hints to the browser that we want binary data. 3701 if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer'; 3702 if (xhr.overrideMimeType) { 3703 xhr.overrideMimeType('text/plain; charset=x-user-defined'); 3704 } 3705 3706 xhr.send(null); 3707 if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); 3708 if (xhr.response !== undefined) { 3709 return new Uint8Array(xhr.response || []); 3710 } else { 3711 return intArrayFromString(xhr.responseText || '', true); 3712 } 3713 }); 3714 var lazyArray = this; 3715 lazyArray.setDataGetter(function(chunkNum) { 3716 var start = chunkNum * chunkSize; 3717 var end = (chunkNum+1) * chunkSize - 1; // including this byte 3718 end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block 3719 if (typeof(lazyArray.chunks[chunkNum]) === "undefined") { 3720 lazyArray.chunks[chunkNum] = doXHR(start, end); 3721 } 3722 if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!"); 3723 return lazyArray.chunks[chunkNum]; 3724 }); 3725 3726 this._length = datalength; 3727 this._chunkSize = chunkSize; 3728 this.lengthKnown = true; 3729 } 3730 if (typeof XMLHttpRequest !== 'undefined') { 3731 if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc'; 3732 var lazyArray = new LazyUint8Array(); 3733 Object.defineProperty(lazyArray, "length", { 3734 get: function() { 3735 if(!this.lengthKnown) { 3736 this.cacheLength(); 3737 } 3738 return this._length; 3739 } 3740 }); 3741 Object.defineProperty(lazyArray, "chunkSize", { 3742 get: function() { 3743 if(!this.lengthKnown) { 3744 this.cacheLength(); 3745 } 3746 return this._chunkSize; 3747 } 3748 }); 3749 3750 var properties = { isDevice: false, contents: lazyArray }; 3751 } else { 3752 var properties = { isDevice: false, url: url }; 3753 } 3754 3755 var node = FS.createFile(parent, name, properties, canRead, canWrite); 3756 // This is a total hack, but I want to get this lazy file code out of the 3757 // core of MEMFS. If we want to keep this lazy file concept I feel it should 3758 // be its own thin LAZYFS proxying calls to MEMFS. 3759 if (properties.contents) { 3760 node.contents = properties.contents; 3761 } else if (properties.url) { 3762 node.contents = null; 3763 node.url = properties.url; 3764 } 3765 // override each stream op with one that tries to force load the lazy file first 3766 var stream_ops = {}; 3767 var keys = Object.keys(node.stream_ops); 3768 keys.forEach(function(key) { 3769 var fn = node.stream_ops[key]; 3770 stream_ops[key] = function forceLoadLazyFile() { 3771 if (!FS.forceLoadFile(node)) { 3772 throw new FS.ErrnoError(ERRNO_CODES.EIO); 3773 } 3774 return fn.apply(null, arguments); 3775 }; 3776 }); 3777 // use a custom read function 3778 stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) { 3779 if (!FS.forceLoadFile(node)) { 3780 throw new FS.ErrnoError(ERRNO_CODES.EIO); 3781 } 3782 var contents = stream.node.contents; 3783 if (position >= contents.length) 3784 return 0; 3785 var size = Math.min(contents.length - position, length); 3786 assert(size >= 0); 3787 if (contents.slice) { // normal array 3788 for (var i = 0; i < size; i++) { 3789 buffer[offset + i] = contents[position + i]; 3790 } 3791 } else { 3792 for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR 3793 buffer[offset + i] = contents.get(position + i); 3794 } 3795 } 3796 return size; 3797 }; 3798 node.stream_ops = stream_ops; 3799 return node; 3800 },createPreloadedFile:function (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn) { 3801 Browser.init(); 3802 // TODO we should allow people to just pass in a complete filename instead 3803 // of parent and name being that we just join them anyways 3804 var fullname = name ? PATH.resolve(PATH.join2(parent, name)) : parent; 3805 function processData(byteArray) { 3806 function finish(byteArray) { 3807 if (!dontCreateFile) { 3808 FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn); 3809 } 3810 if (onload) onload(); 3811 removeRunDependency('cp ' + fullname); 3812 } 3813 var handled = false; 3814 Module['preloadPlugins'].forEach(function(plugin) { 3815 if (handled) return; 3816 if (plugin['canHandle'](fullname)) { 3817 plugin['handle'](byteArray, fullname, finish, function() { 3818 if (onerror) onerror(); 3819 removeRunDependency('cp ' + fullname); 3820 }); 3821 handled = true; 3822 } 3823 }); 3824 if (!handled) finish(byteArray); 3825 } 3826 addRunDependency('cp ' + fullname); 3827 if (typeof url == 'string') { 3828 Browser.asyncLoad(url, function(byteArray) { 3829 processData(byteArray); 3830 }, onerror); 3831 } else { 3832 processData(url); 3833 } 3834 },indexedDB:function () { 3835 return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; 3836 },DB_NAME:function () { 3837 return 'EM_FS_' + window.location.pathname; 3838 },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function (paths, onload, onerror) { 3839 onload = onload || function(){}; 3840 onerror = onerror || function(){}; 3841 var indexedDB = FS.indexedDB(); 3842 try { 3843 var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION); 3844 } catch (e) { 3845 return onerror(e); 3846 } 3847 openRequest.onupgradeneeded = function openRequest_onupgradeneeded() { 3848 console.log('creating db'); 3849 var db = openRequest.result; 3850 db.createObjectStore(FS.DB_STORE_NAME); 3851 }; 3852 openRequest.onsuccess = function openRequest_onsuccess() { 3853 var db = openRequest.result; 3854 var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite'); 3855 var files = transaction.objectStore(FS.DB_STORE_NAME); 3856 var ok = 0, fail = 0, total = paths.length; 3857 function finish() { 3858 if (fail == 0) onload(); else onerror(); 3859 } 3860 paths.forEach(function(path) { 3861 var putRequest = files.put(FS.analyzePath(path).object.contents, path); 3862 putRequest.onsuccess = function putRequest_onsuccess() { ok++; if (ok + fail == total) finish() }; 3863 putRequest.onerror = function putRequest_onerror() { fail++; if (ok + fail == total) finish() }; 3864 }); 3865 transaction.onerror = onerror; 3866 }; 3867 openRequest.onerror = onerror; 3868 },loadFilesFromDB:function (paths, onload, onerror) { 3869 onload = onload || function(){}; 3870 onerror = onerror || function(){}; 3871 var indexedDB = FS.indexedDB(); 3872 try { 3873 var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION); 3874 } catch (e) { 3875 return onerror(e); 3876 } 3877 openRequest.onupgradeneeded = onerror; // no database to load from 3878 openRequest.onsuccess = function openRequest_onsuccess() { 3879 var db = openRequest.result; 3880 try { 3881 var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly'); 3882 } catch(e) { 3883 onerror(e); 3884 return; 3885 } 3886 var files = transaction.objectStore(FS.DB_STORE_NAME); 3887 var ok = 0, fail = 0, total = paths.length; 3888 function finish() { 3889 if (fail == 0) onload(); else onerror(); 3890 } 3891 paths.forEach(function(path) { 3892 var getRequest = files.get(path); 3893 getRequest.onsuccess = function getRequest_onsuccess() { 3894 if (FS.analyzePath(path).exists) { 3895 FS.unlink(path); 3896 } 3897 FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true); 3898 ok++; 3899 if (ok + fail == total) finish(); 3900 }; 3901 getRequest.onerror = function getRequest_onerror() { fail++; if (ok + fail == total) finish() }; 3902 }); 3903 transaction.onerror = onerror; 3904 }; 3905 openRequest.onerror = onerror; 3906 }}; 3907 3908 3909 3910 3911 function _mkport() { throw 'TODO' }var SOCKFS={mount:function (mount) { 3912 return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0); 3913 },createSocket:function (family, type, protocol) { 3914 var streaming = type == 1; 3915 if (protocol) { 3916 assert(streaming == (protocol == 6)); // if SOCK_STREAM, must be tcp 3917 } 3918 3919 // create our internal socket structure 3920 var sock = { 3921 family: family, 3922 type: type, 3923 protocol: protocol, 3924 server: null, 3925 peers: {}, 3926 pending: [], 3927 recv_queue: [], 3928 sock_ops: SOCKFS.websocket_sock_ops 3929 }; 3930 3931 // create the filesystem node to store the socket structure 3932 var name = SOCKFS.nextname(); 3933 var node = FS.createNode(SOCKFS.root, name, 49152, 0); 3934 node.sock = sock; 3935 3936 // and the wrapping stream that enables library functions such 3937 // as read and write to indirectly interact with the socket 3938 var stream = FS.createStream({ 3939 path: name, 3940 node: node, 3941 flags: FS.modeStringToFlags('r+'), 3942 seekable: false, 3943 stream_ops: SOCKFS.stream_ops 3944 }); 3945 3946 // map the new stream to the socket structure (sockets have a 1:1 3947 // relationship with a stream) 3948 sock.stream = stream; 3949 3950 return sock; 3951 },getSocket:function (fd) { 3952 var stream = FS.getStream(fd); 3953 if (!stream || !FS.isSocket(stream.node.mode)) { 3954 return null; 3955 } 3956 return stream.node.sock; 3957 },stream_ops:{poll:function (stream) { 3958 var sock = stream.node.sock; 3959 return sock.sock_ops.poll(sock); 3960 },ioctl:function (stream, request, varargs) { 3961 var sock = stream.node.sock; 3962 return sock.sock_ops.ioctl(sock, request, varargs); 3963 },read:function (stream, buffer, offset, length, position /* ignored */) { 3964 var sock = stream.node.sock; 3965 var msg = sock.sock_ops.recvmsg(sock, length); 3966 if (!msg) { 3967 // socket is closed 3968 return 0; 3969 } 3970 buffer.set(msg.buffer, offset); 3971 return msg.buffer.length; 3972 },write:function (stream, buffer, offset, length, position /* ignored */) { 3973 var sock = stream.node.sock; 3974 return sock.sock_ops.sendmsg(sock, buffer, offset, length); 3975 },close:function (stream) { 3976 var sock = stream.node.sock; 3977 sock.sock_ops.close(sock); 3978 }},nextname:function () { 3979 if (!SOCKFS.nextname.current) { 3980 SOCKFS.nextname.current = 0; 3981 } 3982 return 'socket[' + (SOCKFS.nextname.current++) + ']'; 3983 },websocket_sock_ops:{createPeer:function (sock, addr, port) { 3984 var ws; 3985 3986 if (typeof addr === 'object') { 3987 ws = addr; 3988 addr = null; 3989 port = null; 3990 } 3991 3992 if (ws) { 3993 // for sockets that've already connected (e.g. we're the server) 3994 // we can inspect the _socket property for the address 3995 if (ws._socket) { 3996 addr = ws._socket.remoteAddress; 3997 port = ws._socket.remotePort; 3998 } 3999 // if we're just now initializing a connection to the remote, 4000 // inspect the url property 4001 else { 4002 var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url); 4003 if (!result) { 4004 throw new Error('WebSocket URL must be in the format ws(s)://address:port'); 4005 } 4006 addr = result[1]; 4007 port = parseInt(result[2], 10); 4008 } 4009 } else { 4010 // create the actual websocket object and connect 4011 try { 4012 // runtimeConfig gets set to true if WebSocket runtime configuration is available. 4013 var runtimeConfig = (Module['websocket'] && ('object' === typeof Module['websocket'])); 4014 4015 // The default value is 'ws://' the replace is needed because the compiler replaces "//" comments with '#' 4016 // comments without checking context, so we'd end up with ws:#, the replace swaps the "#" for "//" again. 4017 var url = 'ws:#'.replace('#', '//'); 4018 4019 if (runtimeConfig) { 4020 if ('string' === typeof Module['websocket']['url']) { 4021 url = Module['websocket']['url']; // Fetch runtime WebSocket URL config. 4022 } 4023 } 4024 4025 if (url === 'ws://' || url === 'wss://') { // Is the supplied URL config just a prefix, if so complete it. 4026 url = url + addr + ':' + port; 4027 } 4028 4029 // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set. 4030 var subProtocols = 'binary'; // The default value is 'binary' 4031 4032 if (runtimeConfig) { 4033 if ('string' === typeof Module['websocket']['subprotocol']) { 4034 subProtocols = Module['websocket']['subprotocol']; // Fetch runtime WebSocket subprotocol config. 4035 } 4036 } 4037 4038 // The regex trims the string (removes spaces at the beginning and end, then splits the string by 4039 // <any space>,<any space> into an Array. Whitespace removal is important for Websockify and ws. 4040 subProtocols = subProtocols.replace(/^ +| +$/g,"").split(/ *, */); 4041 4042 // The node ws library API for specifying optional subprotocol is slightly different than the browser's. 4043 var opts = ENVIRONMENT_IS_NODE ? {'protocol': subProtocols.toString()} : subProtocols; 4044 4045 // If node we use the ws library. 4046 var WebSocket = ENVIRONMENT_IS_NODE ? require('ws') : window['WebSocket']; 4047 ws = new WebSocket(url, opts); 4048 ws.binaryType = 'arraybuffer'; 4049 } catch (e) { 4050 throw new FS.ErrnoError(ERRNO_CODES.EHOSTUNREACH); 4051 } 4052 } 4053 4054 4055 var peer = { 4056 addr: addr, 4057 port: port, 4058 socket: ws, 4059 dgram_send_queue: [] 4060 }; 4061 4062 SOCKFS.websocket_sock_ops.addPeer(sock, peer); 4063 SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer); 4064 4065 // if this is a bound dgram socket, send the port number first to allow 4066 // us to override the ephemeral port reported to us by remotePort on the 4067 // remote end. 4068 if (sock.type === 2 && typeof sock.sport !== 'undefined') { 4069 peer.dgram_send_queue.push(new Uint8Array([ 4070 255, 255, 255, 255, 4071 'p'.charCodeAt(0), 'o'.charCodeAt(0), 'r'.charCodeAt(0), 't'.charCodeAt(0), 4072 ((sock.sport & 0xff00) >> 8) , (sock.sport & 0xff) 4073 ])); 4074 } 4075 4076 return peer; 4077 },getPeer:function (sock, addr, port) { 4078 return sock.peers[addr + ':' + port]; 4079 },addPeer:function (sock, peer) { 4080 sock.peers[peer.addr + ':' + peer.port] = peer; 4081 },removePeer:function (sock, peer) { 4082 delete sock.peers[peer.addr + ':' + peer.port]; 4083 },handlePeerEvents:function (sock, peer) { 4084 var first = true; 4085 4086 var handleOpen = function () { 4087 try { 4088 var queued = peer.dgram_send_queue.shift(); 4089 while (queued) { 4090 peer.socket.send(queued); 4091 queued = peer.dgram_send_queue.shift(); 4092 } 4093 } catch (e) { 4094 // not much we can do here in the way of proper error handling as we've already 4095 // lied and said this data was sent. shut it down. 4096 peer.socket.close(); 4097 } 4098 }; 4099 4100 function handleMessage(data) { 4101 assert(typeof data !== 'string' && data.byteLength !== undefined); // must receive an ArrayBuffer 4102 data = new Uint8Array(data); // make a typed array view on the array buffer 4103 4104 4105 // if this is the port message, override the peer's port with it 4106 var wasfirst = first; 4107 first = false; 4108 if (wasfirst && 4109 data.length === 10 && 4110 data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 && 4111 data[4] === 'p'.charCodeAt(0) && data[5] === 'o'.charCodeAt(0) && data[6] === 'r'.charCodeAt(0) && data[7] === 't'.charCodeAt(0)) { 4112 // update the peer's port and it's key in the peer map 4113 var newport = ((data[8] << 8) | data[9]); 4114 SOCKFS.websocket_sock_ops.removePeer(sock, peer); 4115 peer.port = newport; 4116 SOCKFS.websocket_sock_ops.addPeer(sock, peer); 4117 return; 4118 } 4119 4120 sock.recv_queue.push({ addr: peer.addr, port: peer.port, data: data }); 4121 }; 4122 4123 if (ENVIRONMENT_IS_NODE) { 4124 peer.socket.on('open', handleOpen); 4125 peer.socket.on('message', function(data, flags) { 4126 if (!flags.binary) { 4127 return; 4128 } 4129 handleMessage((new Uint8Array(data)).buffer); // copy from node Buffer -> ArrayBuffer 4130 }); 4131 peer.socket.on('error', function() { 4132 // don't throw 4133 }); 4134 } else { 4135 peer.socket.onopen = handleOpen; 4136 peer.socket.onmessage = function peer_socket_onmessage(event) { 4137 handleMessage(event.data); 4138 }; 4139 } 4140 },poll:function (sock) { 4141 if (sock.type === 1 && sock.server) { 4142 // listen sockets should only say they're available for reading 4143 // if there are pending clients. 4144 return sock.pending.length ? (64 | 1) : 0; 4145 } 4146 4147 var mask = 0; 4148 var dest = sock.type === 1 ? // we only care about the socket state for connection-based sockets 4149 SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) : 4150 null; 4151 4152 if (sock.recv_queue.length || 4153 !dest || // connection-less sockets are always ready to read 4154 (dest && dest.socket.readyState === dest.socket.CLOSING) || 4155 (dest && dest.socket.readyState === dest.socket.CLOSED)) { // let recv return 0 once closed 4156 mask |= (64 | 1); 4157 } 4158 4159 if (!dest || // connection-less sockets are always ready to write 4160 (dest && dest.socket.readyState === dest.socket.OPEN)) { 4161 mask |= 4; 4162 } 4163 4164 if ((dest && dest.socket.readyState === dest.socket.CLOSING) || 4165 (dest && dest.socket.readyState === dest.socket.CLOSED)) { 4166 mask |= 16; 4167 } 4168 4169 return mask; 4170 },ioctl:function (sock, request, arg) { 4171 switch (request) { 4172 case 21531: 4173 var bytes = 0; 4174 if (sock.recv_queue.length) { 4175 bytes = sock.recv_queue[0].data.length; 4176 } 4177 HEAP32[((arg)>>2)]=bytes; 4178 return 0; 4179 default: 4180 return ERRNO_CODES.EINVAL; 4181 } 4182 },close:function (sock) { 4183 // if we've spawned a listen server, close it 4184 if (sock.server) { 4185 try { 4186 sock.server.close(); 4187 } catch (e) { 4188 } 4189 sock.server = null; 4190 } 4191 // close any peer connections 4192 var peers = Object.keys(sock.peers); 4193 for (var i = 0; i < peers.length; i++) { 4194 var peer = sock.peers[peers[i]]; 4195 try { 4196 peer.socket.close(); 4197 } catch (e) { 4198 } 4199 SOCKFS.websocket_sock_ops.removePeer(sock, peer); 4200 } 4201 return 0; 4202 },bind:function (sock, addr, port) { 4203 if (typeof sock.saddr !== 'undefined' || typeof sock.sport !== 'undefined') { 4204 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); // already bound 4205 } 4206 sock.saddr = addr; 4207 sock.sport = port || _mkport(); 4208 // in order to emulate dgram sockets, we need to launch a listen server when 4209 // binding on a connection-less socket 4210 // note: this is only required on the server side 4211 if (sock.type === 2) { 4212 // close the existing server if it exists 4213 if (sock.server) { 4214 sock.server.close(); 4215 sock.server = null; 4216 } 4217 // swallow error operation not supported error that occurs when binding in the 4218 // browser where this isn't supported 4219 try { 4220 sock.sock_ops.listen(sock, 0); 4221 } catch (e) { 4222 if (!(e instanceof FS.ErrnoError)) throw e; 4223 if (e.errno !== ERRNO_CODES.EOPNOTSUPP) throw e; 4224 } 4225 } 4226 },connect:function (sock, addr, port) { 4227 if (sock.server) { 4228 throw new FS.ErrnoError(ERRNO_CODS.EOPNOTSUPP); 4229 } 4230 4231 // TODO autobind 4232 // if (!sock.addr && sock.type == 2) { 4233 // } 4234 4235 // early out if we're already connected / in the middle of connecting 4236 if (typeof sock.daddr !== 'undefined' && typeof sock.dport !== 'undefined') { 4237 var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport); 4238 if (dest) { 4239 if (dest.socket.readyState === dest.socket.CONNECTING) { 4240 throw new FS.ErrnoError(ERRNO_CODES.EALREADY); 4241 } else { 4242 throw new FS.ErrnoError(ERRNO_CODES.EISCONN); 4243 } 4244 } 4245 } 4246 4247 // add the socket to our peer list and set our 4248 // destination address / port to match 4249 var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port); 4250 sock.daddr = peer.addr; 4251 sock.dport = peer.port; 4252 4253 // always "fail" in non-blocking mode 4254 throw new FS.ErrnoError(ERRNO_CODES.EINPROGRESS); 4255 },listen:function (sock, backlog) { 4256 if (!ENVIRONMENT_IS_NODE) { 4257 throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP); 4258 } 4259 if (sock.server) { 4260 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); // already listening 4261 } 4262 var WebSocketServer = require('ws').Server; 4263 var host = sock.saddr; 4264 sock.server = new WebSocketServer({ 4265 host: host, 4266 port: sock.sport 4267 // TODO support backlog 4268 }); 4269 4270 sock.server.on('connection', function(ws) { 4271 if (sock.type === 1) { 4272 var newsock = SOCKFS.createSocket(sock.family, sock.type, sock.protocol); 4273 4274 // create a peer on the new socket 4275 var peer = SOCKFS.websocket_sock_ops.createPeer(newsock, ws); 4276 newsock.daddr = peer.addr; 4277 newsock.dport = peer.port; 4278 4279 // push to queue for accept to pick up 4280 sock.pending.push(newsock); 4281 } else { 4282 // create a peer on the listen socket so calling sendto 4283 // with the listen socket and an address will resolve 4284 // to the correct client 4285 SOCKFS.websocket_sock_ops.createPeer(sock, ws); 4286 } 4287 }); 4288 sock.server.on('closed', function() { 4289 sock.server = null; 4290 }); 4291 sock.server.on('error', function() { 4292 // don't throw 4293 }); 4294 },accept:function (listensock) { 4295 if (!listensock.server) { 4296 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 4297 } 4298 var newsock = listensock.pending.shift(); 4299 newsock.stream.flags = listensock.stream.flags; 4300 return newsock; 4301 },getname:function (sock, peer) { 4302 var addr, port; 4303 if (peer) { 4304 if (sock.daddr === undefined || sock.dport === undefined) { 4305 throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN); 4306 } 4307 addr = sock.daddr; 4308 port = sock.dport; 4309 } else { 4310 // TODO saddr and sport will be set for bind()'d UDP sockets, but what 4311 // should we be returning for TCP sockets that've been connect()'d? 4312 addr = sock.saddr || 0; 4313 port = sock.sport || 0; 4314 } 4315 return { addr: addr, port: port }; 4316 },sendmsg:function (sock, buffer, offset, length, addr, port) { 4317 if (sock.type === 2) { 4318 // connection-less sockets will honor the message address, 4319 // and otherwise fall back to the bound destination address 4320 if (addr === undefined || port === undefined) { 4321 addr = sock.daddr; 4322 port = sock.dport; 4323 } 4324 // if there was no address to fall back to, error out 4325 if (addr === undefined || port === undefined) { 4326 throw new FS.ErrnoError(ERRNO_CODES.EDESTADDRREQ); 4327 } 4328 } else { 4329 // connection-based sockets will only use the bound 4330 addr = sock.daddr; 4331 port = sock.dport; 4332 } 4333 4334 // find the peer for the destination address 4335 var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port); 4336 4337 // early out if not connected with a connection-based socket 4338 if (sock.type === 1) { 4339 if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) { 4340 throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN); 4341 } else if (dest.socket.readyState === dest.socket.CONNECTING) { 4342 throw new FS.ErrnoError(ERRNO_CODES.EAGAIN); 4343 } 4344 } 4345 4346 // create a copy of the incoming data to send, as the WebSocket API 4347 // doesn't work entirely with an ArrayBufferView, it'll just send 4348 // the entire underlying buffer 4349 var data; 4350 if (buffer instanceof Array || buffer instanceof ArrayBuffer) { 4351 data = buffer.slice(offset, offset + length); 4352 } else { // ArrayBufferView 4353 data = buffer.buffer.slice(buffer.byteOffset + offset, buffer.byteOffset + offset + length); 4354 } 4355 4356 // if we're emulating a connection-less dgram socket and don't have 4357 // a cached connection, queue the buffer to send upon connect and 4358 // lie, saying the data was sent now. 4359 if (sock.type === 2) { 4360 if (!dest || dest.socket.readyState !== dest.socket.OPEN) { 4361 // if we're not connected, open a new connection 4362 if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) { 4363 dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port); 4364 } 4365 dest.dgram_send_queue.push(data); 4366 return length; 4367 } 4368 } 4369 4370 try { 4371 // send the actual data 4372 dest.socket.send(data); 4373 return length; 4374 } catch (e) { 4375 throw new FS.ErrnoError(ERRNO_CODES.EINVAL); 4376 } 4377 },recvmsg:function (sock, length) { 4378 // http://pubs.opengroup.org/onlinepubs/7908799/xns/recvmsg.html 4379 if (sock.type === 1 && sock.server) { 4380 // tcp servers should not be recv()'ing on the listen socket 4381 throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN); 4382 } 4383 4384 var queued = sock.recv_queue.shift(); 4385 if (!queued) { 4386 if (sock.type === 1) { 4387 var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport); 4388 4389 if (!dest) { 4390 // if we have a destination address but are not connected, error out 4391 throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN); 4392 } 4393 else if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) { 4394 // return null if the socket has closed 4395 return null; 4396 } 4397 else { 4398 // else, our socket is in a valid state but truly has nothing available 4399 throw new FS.ErrnoError(ERRNO_CODES.EAGAIN); 4400 } 4401 } else { 4402 throw new FS.ErrnoError(ERRNO_CODES.EAGAIN); 4403 } 4404 } 4405 4406 // queued.data will be an ArrayBuffer if it's unadulterated, but if it's 4407 // requeued TCP data it'll be an ArrayBufferView 4408 var queuedLength = queued.data.byteLength || queued.data.length; 4409 var queuedOffset = queued.data.byteOffset || 0; 4410 var queuedBuffer = queued.data.buffer || queued.data; 4411 var bytesRead = Math.min(length, queuedLength); 4412 var res = { 4413 buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead), 4414 addr: queued.addr, 4415 port: queued.port 4416 }; 4417 4418 4419 // push back any unread data for TCP connections 4420 if (sock.type === 1 && bytesRead < queuedLength) { 4421 var bytesRemaining = queuedLength - bytesRead; 4422 queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining); 4423 sock.recv_queue.unshift(queued); 4424 } 4425 4426 return res; 4427 }}};function _send(fd, buf, len, flags) { 4428 var sock = SOCKFS.getSocket(fd); 4429 if (!sock) { 4430 ___setErrNo(ERRNO_CODES.EBADF); 4431 return -1; 4432 } 4433 // TODO honor flags 4434 return _write(fd, buf, len); 4435 } 4436 4437 function _pwrite(fildes, buf, nbyte, offset) { 4438 // ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset); 4439 // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html 4440 var stream = FS.getStream(fildes); 4441 if (!stream) { 4442 ___setErrNo(ERRNO_CODES.EBADF); 4443 return -1; 4444 } 4445 try { 4446 var slab = HEAP8; 4447 return FS.write(stream, slab, buf, nbyte, offset); 4448 } catch (e) { 4449 FS.handleFSError(e); 4450 return -1; 4451 } 4452 }function _write(fildes, buf, nbyte) { 4453 // ssize_t write(int fildes, const void *buf, size_t nbyte); 4454 // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html 4455 var stream = FS.getStream(fildes); 4456 if (!stream) { 4457 ___setErrNo(ERRNO_CODES.EBADF); 4458 return -1; 4459 } 4460 4461 4462 try { 4463 var slab = HEAP8; 4464 return FS.write(stream, slab, buf, nbyte); 4465 } catch (e) { 4466 FS.handleFSError(e); 4467 return -1; 4468 } 4469 } 4470 4471 function _fileno(stream) { 4472 // int fileno(FILE *stream); 4473 // http://pubs.opengroup.org/onlinepubs/000095399/functions/fileno.html 4474 stream = FS.getStreamFromPtr(stream); 4475 if (!stream) return -1; 4476 return stream.fd; 4477 }function _fwrite(ptr, size, nitems, stream) { 4478 // size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream); 4479 // http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html 4480 var bytesToWrite = nitems * size; 4481 if (bytesToWrite == 0) return 0; 4482 var fd = _fileno(stream); 4483 var bytesWritten = _write(fd, ptr, bytesToWrite); 4484 if (bytesWritten == -1) { 4485 var streamObj = FS.getStreamFromPtr(stream); 4486 if (streamObj) streamObj.error = true; 4487 return 0; 4488 } else { 4489 return Math.floor(bytesWritten / size); 4490 } 4491 } 4492 4493 4494 4495 Module["_strlen"] = _strlen; 4496 4497 function __reallyNegative(x) { 4498 return x < 0 || (x === 0 && (1/x) === -Infinity); 4499 }function __formatString(format, varargs) { 4500 var textIndex = format; 4501 var argIndex = 0; 4502 function getNextArg(type) { 4503 // NOTE: Explicitly ignoring type safety. Otherwise this fails: 4504 // int x = 4; printf("%c\n", (char)x); 4505 var ret; 4506 if (type === 'double') { 4507 ret = HEAPF64[(((varargs)+(argIndex))>>3)]; 4508 } else if (type == 'i64') { 4509 ret = [HEAP32[(((varargs)+(argIndex))>>2)], 4510 HEAP32[(((varargs)+(argIndex+4))>>2)]]; 4511 4512 } else { 4513 type = 'i32'; // varargs are always i32, i64, or double 4514 ret = HEAP32[(((varargs)+(argIndex))>>2)]; 4515 } 4516 argIndex += Runtime.getNativeFieldSize(type); 4517 return ret; 4518 } 4519 4520 var ret = []; 4521 var curr, next, currArg; 4522 while(1) { 4523 var startTextIndex = textIndex; 4524 curr = HEAP8[(textIndex)]; 4525 if (curr === 0) break; 4526 next = HEAP8[((textIndex+1)|0)]; 4527 if (curr == 37) { 4528 // Handle flags. 4529 var flagAlwaysSigned = false; 4530 var flagLeftAlign = false; 4531 var flagAlternative = false; 4532 var flagZeroPad = false; 4533 var flagPadSign = false; 4534 flagsLoop: while (1) { 4535 switch (next) { 4536 case 43: 4537 flagAlwaysSigned = true; 4538 break; 4539 case 45: 4540 flagLeftAlign = true; 4541 break; 4542 case 35: 4543 flagAlternative = true; 4544 break; 4545 case 48: 4546 if (flagZeroPad) { 4547 break flagsLoop; 4548 } else { 4549 flagZeroPad = true; 4550 break; 4551 } 4552 case 32: 4553 flagPadSign = true; 4554 break; 4555 default: 4556 break flagsLoop; 4557 } 4558 textIndex++; 4559 next = HEAP8[((textIndex+1)|0)]; 4560 } 4561 4562 // Handle width. 4563 var width = 0; 4564 if (next == 42) { 4565 width = getNextArg('i32'); 4566 textIndex++; 4567 next = HEAP8[((textIndex+1)|0)]; 4568 } else { 4569 while (next >= 48 && next <= 57) { 4570 width = width * 10 + (next - 48); 4571 textIndex++; 4572 next = HEAP8[((textIndex+1)|0)]; 4573 } 4574 } 4575 4576 // Handle precision. 4577 var precisionSet = false, precision = -1; 4578 if (next == 46) { 4579 precision = 0; 4580 precisionSet = true; 4581 textIndex++; 4582 next = HEAP8[((textIndex+1)|0)]; 4583 if (next == 42) { 4584 precision = getNextArg('i32'); 4585 textIndex++; 4586 } else { 4587 while(1) { 4588 var precisionChr = HEAP8[((textIndex+1)|0)]; 4589 if (precisionChr < 48 || 4590 precisionChr > 57) break; 4591 precision = precision * 10 + (precisionChr - 48); 4592 textIndex++; 4593 } 4594 } 4595 next = HEAP8[((textIndex+1)|0)]; 4596 } 4597 if (precision < 0) { 4598 precision = 6; // Standard default. 4599 precisionSet = false; 4600 } 4601 4602 // Handle integer sizes. WARNING: These assume a 32-bit architecture! 4603 var argSize; 4604 switch (String.fromCharCode(next)) { 4605 case 'h': 4606 var nextNext = HEAP8[((textIndex+2)|0)]; 4607 if (nextNext == 104) { 4608 textIndex++; 4609 argSize = 1; // char (actually i32 in varargs) 4610 } else { 4611 argSize = 2; // short (actually i32 in varargs) 4612 } 4613 break; 4614 case 'l': 4615 var nextNext = HEAP8[((textIndex+2)|0)]; 4616 if (nextNext == 108) { 4617 textIndex++; 4618 argSize = 8; // long long 4619 } else { 4620 argSize = 4; // long 4621 } 4622 break; 4623 case 'L': // long long 4624 case 'q': // int64_t 4625 case 'j': // intmax_t 4626 argSize = 8; 4627 break; 4628 case 'z': // size_t 4629 case 't': // ptrdiff_t 4630 case 'I': // signed ptrdiff_t or unsigned size_t 4631 argSize = 4; 4632 break; 4633 default: 4634 argSize = null; 4635 } 4636 if (argSize) textIndex++; 4637 next = HEAP8[((textIndex+1)|0)]; 4638 4639 // Handle type specifier. 4640 switch (String.fromCharCode(next)) { 4641 case 'd': case 'i': case 'u': case 'o': case 'x': case 'X': case 'p': { 4642 // Integer. 4643 var signed = next == 100 || next == 105; 4644 argSize = argSize || 4; 4645 var currArg = getNextArg('i' + (argSize * 8)); 4646 var argText; 4647 // Flatten i64-1 [low, high] into a (slightly rounded) double 4648 if (argSize == 8) { 4649 currArg = Runtime.makeBigInt(currArg[0], currArg[1], next == 117); 4650 } 4651 // Truncate to requested size. 4652 if (argSize <= 4) { 4653 var limit = Math.pow(256, argSize) - 1; 4654 currArg = (signed ? reSign : unSign)(currArg & limit, argSize * 8); 4655 } 4656 // Format the number. 4657 var currAbsArg = Math.abs(currArg); 4658 var prefix = ''; 4659 if (next == 100 || next == 105) { 4660 argText = reSign(currArg, 8 * argSize, 1).toString(10); 4661 } else if (next == 117) { 4662 argText = unSign(currArg, 8 * argSize, 1).toString(10); 4663 currArg = Math.abs(currArg); 4664 } else if (next == 111) { 4665 argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8); 4666 } else if (next == 120 || next == 88) { 4667 prefix = (flagAlternative && currArg != 0) ? '0x' : ''; 4668 if (currArg < 0) { 4669 // Represent negative numbers in hex as 2's complement. 4670 currArg = -currArg; 4671 argText = (currAbsArg - 1).toString(16); 4672 var buffer = []; 4673 for (var i = 0; i < argText.length; i++) { 4674 buffer.push((0xF - parseInt(argText[i], 16)).toString(16)); 4675 } 4676 argText = buffer.join(''); 4677 while (argText.length < argSize * 2) argText = 'f' + argText; 4678 } else { 4679 argText = currAbsArg.toString(16); 4680 } 4681 if (next == 88) { 4682 prefix = prefix.toUpperCase(); 4683 argText = argText.toUpperCase(); 4684 } 4685 } else if (next == 112) { 4686 if (currAbsArg === 0) { 4687 argText = '(nil)'; 4688 } else { 4689 prefix = '0x'; 4690 argText = currAbsArg.toString(16); 4691 } 4692 } 4693 if (precisionSet) { 4694 while (argText.length < precision) { 4695 argText = '0' + argText; 4696 } 4697 } 4698 4699 // Add sign if needed 4700 if (currArg >= 0) { 4701 if (flagAlwaysSigned) { 4702 prefix = '+' + prefix; 4703 } else if (flagPadSign) { 4704 prefix = ' ' + prefix; 4705 } 4706 } 4707 4708 // Move sign to prefix so we zero-pad after the sign 4709 if (argText.charAt(0) == '-') { 4710 prefix = '-' + prefix; 4711 argText = argText.substr(1); 4712 } 4713 4714 // Add padding. 4715 while (prefix.length + argText.length < width) { 4716 if (flagLeftAlign) { 4717 argText += ' '; 4718 } else { 4719 if (flagZeroPad) { 4720 argText = '0' + argText; 4721 } else { 4722 prefix = ' ' + prefix; 4723 } 4724 } 4725 } 4726 4727 // Insert the result into the buffer. 4728 argText = prefix + argText; 4729 argText.split('').forEach(function(chr) { 4730 ret.push(chr.charCodeAt(0)); 4731 }); 4732 break; 4733 } 4734 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': { 4735 // Float. 4736 var currArg = getNextArg('double'); 4737 var argText; 4738 if (isNaN(currArg)) { 4739 argText = 'nan'; 4740 flagZeroPad = false; 4741 } else if (!isFinite(currArg)) { 4742 argText = (currArg < 0 ? '-' : '') + 'inf'; 4743 flagZeroPad = false; 4744 } else { 4745 var isGeneral = false; 4746 var effectivePrecision = Math.min(precision, 20); 4747 4748 // Convert g/G to f/F or e/E, as per: 4749 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html 4750 if (next == 103 || next == 71) { 4751 isGeneral = true; 4752 precision = precision || 1; 4753 var exponent = parseInt(currArg.toExponential(effectivePrecision).split('e')[1], 10); 4754 if (precision > exponent && exponent >= -4) { 4755 next = ((next == 103) ? 'f' : 'F').charCodeAt(0); 4756 precision -= exponent + 1; 4757 } else { 4758 next = ((next == 103) ? 'e' : 'E').charCodeAt(0); 4759 precision--; 4760 } 4761 effectivePrecision = Math.min(precision, 20); 4762 } 4763 4764 if (next == 101 || next == 69) { 4765 argText = currArg.toExponential(effectivePrecision); 4766 // Make sure the exponent has at least 2 digits. 4767 if (/[eE][-+]\d$/.test(argText)) { 4768 argText = argText.slice(0, -1) + '0' + argText.slice(-1); 4769 } 4770 } else if (next == 102 || next == 70) { 4771 argText = currArg.toFixed(effectivePrecision); 4772 if (currArg === 0 && __reallyNegative(currArg)) { 4773 argText = '-' + argText; 4774 } 4775 } 4776 4777 var parts = argText.split('e'); 4778 if (isGeneral && !flagAlternative) { 4779 // Discard trailing zeros and periods. 4780 while (parts[0].length > 1 && parts[0].indexOf('.') != -1 && 4781 (parts[0].slice(-1) == '0' || parts[0].slice(-1) == '.')) { 4782 parts[0] = parts[0].slice(0, -1); 4783 } 4784 } else { 4785 // Make sure we have a period in alternative mode. 4786 if (flagAlternative && argText.indexOf('.') == -1) parts[0] += '.'; 4787 // Zero pad until required precision. 4788 while (precision > effectivePrecision++) parts[0] += '0'; 4789 } 4790 argText = parts[0] + (parts.length > 1 ? 'e' + parts[1] : ''); 4791 4792 // Capitalize 'E' if needed. 4793 if (next == 69) argText = argText.toUpperCase(); 4794 4795 // Add sign. 4796 if (currArg >= 0) { 4797 if (flagAlwaysSigned) { 4798 argText = '+' + argText; 4799 } else if (flagPadSign) { 4800 argText = ' ' + argText; 4801 } 4802 } 4803 } 4804 4805 // Add padding. 4806 while (argText.length < width) { 4807 if (flagLeftAlign) { 4808 argText += ' '; 4809 } else { 4810 if (flagZeroPad && (argText[0] == '-' || argText[0] == '+')) { 4811 argText = argText[0] + '0' + argText.slice(1); 4812 } else { 4813 argText = (flagZeroPad ? '0' : ' ') + argText; 4814 } 4815 } 4816 } 4817 4818 // Adjust case. 4819 if (next < 97) argText = argText.toUpperCase(); 4820 4821 // Insert the result into the buffer. 4822 argText.split('').forEach(function(chr) { 4823 ret.push(chr.charCodeAt(0)); 4824 }); 4825 break; 4826 } 4827 case 's': { 4828 // String. 4829 var arg = getNextArg('i8*'); 4830 var argLength = arg ? _strlen(arg) : '(null)'.length; 4831 if (precisionSet) argLength = Math.min(argLength, precision); 4832 if (!flagLeftAlign) { 4833 while (argLength < width--) { 4834 ret.push(32); 4835 } 4836 } 4837 if (arg) { 4838 for (var i = 0; i < argLength; i++) { 4839 ret.push(HEAPU8[((arg++)|0)]); 4840 } 4841 } else { 4842 ret = ret.concat(intArrayFromString('(null)'.substr(0, argLength), true)); 4843 } 4844 if (flagLeftAlign) { 4845 while (argLength < width--) { 4846 ret.push(32); 4847 } 4848 } 4849 break; 4850 } 4851 case 'c': { 4852 // Character. 4853 if (flagLeftAlign) ret.push(getNextArg('i8')); 4854 while (--width > 0) { 4855 ret.push(32); 4856 } 4857 if (!flagLeftAlign) ret.push(getNextArg('i8')); 4858 break; 4859 } 4860 case 'n': { 4861 // Write the length written so far to the next parameter. 4862 var ptr = getNextArg('i32*'); 4863 HEAP32[((ptr)>>2)]=ret.length; 4864 break; 4865 } 4866 case '%': { 4867 // Literal percent sign. 4868 ret.push(curr); 4869 break; 4870 } 4871 default: { 4872 // Unknown specifiers remain untouched. 4873 for (var i = startTextIndex; i < textIndex + 2; i++) { 4874 ret.push(HEAP8[(i)]); 4875 } 4876 } 4877 } 4878 textIndex += 2; 4879 // TODO: Support a/A (hex float) and m (last error) specifiers. 4880 // TODO: Support %1${specifier} for arg selection. 4881 } else { 4882 ret.push(curr); 4883 textIndex += 1; 4884 } 4885 } 4886 return ret; 4887 }function _fprintf(stream, format, varargs) { 4888 // int fprintf(FILE *restrict stream, const char *restrict format, ...); 4889 // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html 4890 var result = __formatString(format, varargs); 4891 var stack = Runtime.stackSave(); 4892 var ret = _fwrite(allocate(result, 'i8', ALLOC_STACK), 1, result.length, stream); 4893 Runtime.stackRestore(stack); 4894 return ret; 4895 }function _printf(format, varargs) { 4896 // int printf(const char *restrict format, ...); 4897 // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html 4898 var stdout = HEAP32[((_stdout)>>2)]; 4899 return _fprintf(stdout, format, varargs); 4900 } 4901 4902 4903 function _fputc(c, stream) { 4904 // int fputc(int c, FILE *stream); 4905 // http://pubs.opengroup.org/onlinepubs/000095399/functions/fputc.html 4906 var chr = unSign(c & 0xFF); 4907 HEAP8[((_fputc.ret)|0)]=chr; 4908 var fd = _fileno(stream); 4909 var ret = _write(fd, _fputc.ret, 1); 4910 if (ret == -1) { 4911 var streamObj = FS.getStreamFromPtr(stream); 4912 if (streamObj) streamObj.error = true; 4913 return -1; 4914 } else { 4915 return chr; 4916 } 4917 }function _putchar(c) { 4918 // int putchar(int c); 4919 // http://pubs.opengroup.org/onlinepubs/000095399/functions/putchar.html 4920 return _fputc(c, HEAP32[((_stdout)>>2)]); 4921 } 4922 4923 function _sbrk(bytes) { 4924 // Implement a Linux-like 'memory area' for our 'process'. 4925 // Changes the size of the memory area by |bytes|; returns the 4926 // address of the previous top ('break') of the memory area 4927 // We control the "dynamic" memory - DYNAMIC_BASE to DYNAMICTOP 4928 var self = _sbrk; 4929 if (!self.called) { 4930 DYNAMICTOP = alignMemoryPage(DYNAMICTOP); // make sure we start out aligned 4931 self.called = true; 4932 assert(Runtime.dynamicAlloc); 4933 self.alloc = Runtime.dynamicAlloc; 4934 Runtime.dynamicAlloc = function() { abort('cannot dynamically allocate, sbrk now has control') }; 4935 } 4936 var ret = DYNAMICTOP; 4937 if (bytes != 0) self.alloc(bytes); 4938 return ret; // Previous break location. 4939 } 4940 4941 function _sysconf(name) { 4942 // long sysconf(int name); 4943 // http://pubs.opengroup.org/onlinepubs/009695399/functions/sysconf.html 4944 switch(name) { 4945 case 30: return PAGE_SIZE; 4946 case 132: 4947 case 133: 4948 case 12: 4949 case 137: 4950 case 138: 4951 case 15: 4952 case 235: 4953 case 16: 4954 case 17: 4955 case 18: 4956 case 19: 4957 case 20: 4958 case 149: 4959 case 13: 4960 case 10: 4961 case 236: 4962 case 153: 4963 case 9: 4964 case 21: 4965 case 22: 4966 case 159: 4967 case 154: 4968 case 14: 4969 case 77: 4970 case 78: 4971 case 139: 4972 case 80: 4973 case 81: 4974 case 79: 4975 case 82: 4976 case 68: 4977 case 67: 4978 case 164: 4979 case 11: 4980 case 29: 4981 case 47: 4982 case 48: 4983 case 95: 4984 case 52: 4985 case 51: 4986 case 46: 4987 return 200809; 4988 case 27: 4989 case 246: 4990 case 127: 4991 case 128: 4992 case 23: 4993 case 24: 4994 case 160: 4995 case 161: 4996 case 181: 4997 case 182: 4998 case 242: 4999 case 183: 5000 case 184: 5001 case 243: 5002 case 244: 5003 case 245: 5004 case 165: 5005 case 178: 5006 case 179: 5007 case 49: 5008 case 50: 5009 case 168: 5010 case 169: 5011 case 175: 5012 case 170: 5013 case 171: 5014 case 172: 5015 case 97: 5016 case 76: 5017 case 32: 5018 case 173: 5019 case 35: 5020 return -1; 5021 case 176: 5022 case 177: 5023 case 7: 5024 case 155: 5025 case 8: 5026 case 157: 5027 case 125: 5028 case 126: 5029 case 92: 5030 case 93: 5031 case 129: 5032 case 130: 5033 case 131: 5034 case 94: 5035 case 91: 5036 return 1; 5037 case 74: 5038 case 60: 5039 case 69: 5040 case 70: 5041 case 4: 5042 return 1024; 5043 case 31: 5044 case 42: 5045 case 72: 5046 return 32; 5047 case 87: 5048 case 26: 5049 case 33: 5050 return 2147483647; 5051 case 34: 5052 case 1: 5053 return 47839; 5054 case 38: 5055 case 36: 5056 return 99; 5057 case 43: 5058 case 37: 5059 return 2048; 5060 case 0: return 2097152; 5061 case 3: return 65536; 5062 case 28: return 32768; 5063 case 44: return 32767; 5064 case 75: return 16384; 5065 case 39: return 1000; 5066 case 89: return 700; 5067 case 71: return 256; 5068 case 40: return 255; 5069 case 2: return 100; 5070 case 180: return 64; 5071 case 25: return 20; 5072 case 5: return 16; 5073 case 6: return 6; 5074 case 73: return 4; 5075 case 84: return 1; 5076 } 5077 ___setErrNo(ERRNO_CODES.EINVAL); 5078 return -1; 5079 } 5080 5081 5082 Module["_memset"] = _memset; 5083 5084 function ___errno_location() { 5085 return ___errno_state; 5086 } 5087 5088 function _abort() { 5089 Module['abort'](); 5090 } 5091 5092 var Browser={mainLoop:{scheduler:null,method:"",shouldPause:false,paused:false,queue:[],pause:function () { 5093 Browser.mainLoop.shouldPause = true; 5094 },resume:function () { 5095 if (Browser.mainLoop.paused) { 5096 Browser.mainLoop.paused = false; 5097 Browser.mainLoop.scheduler(); 5098 } 5099 Browser.mainLoop.shouldPause = false; 5100 },updateStatus:function () { 5101 if (Module['setStatus']) { 5102 var message = Module['statusMessage'] || 'Please wait...'; 5103 var remaining = Browser.mainLoop.remainingBlockers; 5104 var expected = Browser.mainLoop.expectedBlockers; 5105 if (remaining) { 5106 if (remaining < expected) { 5107 Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')'); 5108 } else { 5109 Module['setStatus'](message); 5110 } 5111 } else { 5112 Module['setStatus'](''); 5113 } 5114 } 5115 }},isFullScreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function () { 5116 if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers 5117 5118 if (Browser.initted || ENVIRONMENT_IS_WORKER) return; 5119 Browser.initted = true; 5120 5121 try { 5122 new Blob(); 5123 Browser.hasBlobConstructor = true; 5124 } catch(e) { 5125 Browser.hasBlobConstructor = false; 5126 console.log("warning: no blob constructor, cannot create blobs with mimetypes"); 5127 } 5128 Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null)); 5129 Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined; 5130 if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') { 5131 console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available."); 5132 Module.noImageDecoding = true; 5133 } 5134 5135 // Support for plugins that can process preloaded files. You can add more of these to 5136 // your app by creating and appending to Module.preloadPlugins. 5137 // 5138 // Each plugin is asked if it can handle a file based on the file's name. If it can, 5139 // it is given the file's raw data. When it is done, it calls a callback with the file's 5140 // (possibly modified) data. For example, a plugin might decompress a file, or it 5141 // might create some side data structure for use later (like an Image element, etc.). 5142 5143 var imagePlugin = {}; 5144 imagePlugin['canHandle'] = function imagePlugin_canHandle(name) { 5145 return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name); 5146 }; 5147 imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) { 5148 var b = null; 5149 if (Browser.hasBlobConstructor) { 5150 try { 5151 b = new Blob([byteArray], { type: Browser.getMimetype(name) }); 5152 if (b.size !== byteArray.length) { // Safari bug #118630 5153 // Safari's Blob can only take an ArrayBuffer 5154 b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) }); 5155 } 5156 } catch(e) { 5157 Runtime.warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder'); 5158 } 5159 } 5160 if (!b) { 5161 var bb = new Browser.BlobBuilder(); 5162 bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range 5163 b = bb.getBlob(); 5164 } 5165 var url = Browser.URLObject.createObjectURL(b); 5166 var img = new Image(); 5167 img.onload = function img_onload() { 5168 assert(img.complete, 'Image ' + name + ' could not be decoded'); 5169 var canvas = document.createElement('canvas'); 5170 canvas.width = img.width; 5171 canvas.height = img.height; 5172 var ctx = canvas.getContext('2d'); 5173 ctx.drawImage(img, 0, 0); 5174 Module["preloadedImages"][name] = canvas; 5175 Browser.URLObject.revokeObjectURL(url); 5176 if (onload) onload(byteArray); 5177 }; 5178 img.onerror = function img_onerror(event) { 5179 console.log('Image ' + url + ' could not be decoded'); 5180 if (onerror) onerror(); 5181 }; 5182 img.src = url; 5183 }; 5184 Module['preloadPlugins'].push(imagePlugin); 5185 5186 var audioPlugin = {}; 5187 audioPlugin['canHandle'] = function audioPlugin_canHandle(name) { 5188 return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 }; 5189 }; 5190 audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) { 5191 var done = false; 5192 function finish(audio) { 5193 if (done) return; 5194 done = true; 5195 Module["preloadedAudios"][name] = audio; 5196 if (onload) onload(byteArray); 5197 } 5198 function fail() { 5199 if (done) return; 5200 done = true; 5201 Module["preloadedAudios"][name] = new Audio(); // empty shim 5202 if (onerror) onerror(); 5203 } 5204 if (Browser.hasBlobConstructor) { 5205 try { 5206 var b = new Blob([byteArray], { type: Browser.getMimetype(name) }); 5207 } catch(e) { 5208 return fail(); 5209 } 5210 var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this! 5211 var audio = new Audio(); 5212 audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926 5213 audio.onerror = function audio_onerror(event) { 5214 if (done) return; 5215 console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach'); 5216 function encode64(data) { 5217 var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 5218 var PAD = '='; 5219 var ret = ''; 5220 var leftchar = 0; 5221 var leftbits = 0; 5222 for (var i = 0; i < data.length; i++) { 5223 leftchar = (leftchar << 8) | data[i]; 5224 leftbits += 8; 5225 while (leftbits >= 6) { 5226 var curr = (leftchar >> (leftbits-6)) & 0x3f; 5227 leftbits -= 6; 5228 ret += BASE[curr]; 5229 } 5230 } 5231 if (leftbits == 2) { 5232 ret += BASE[(leftchar&3) << 4]; 5233 ret += PAD + PAD; 5234 } else if (leftbits == 4) { 5235 ret += BASE[(leftchar&0xf) << 2]; 5236 ret += PAD; 5237 } 5238 return ret; 5239 } 5240 audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray); 5241 finish(audio); // we don't wait for confirmation this worked - but it's worth trying 5242 }; 5243 audio.src = url; 5244 // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror 5245 Browser.safeSetTimeout(function() { 5246 finish(audio); // try to use it even though it is not necessarily ready to play 5247 }, 10000); 5248 } else { 5249 return fail(); 5250 } 5251 }; 5252 Module['preloadPlugins'].push(audioPlugin); 5253 5254 // Canvas event setup 5255 5256 var canvas = Module['canvas']; 5257 5258 // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module 5259 // Module['forcedAspectRatio'] = 4 / 3; 5260 5261 canvas.requestPointerLock = canvas['requestPointerLock'] || 5262 canvas['mozRequestPointerLock'] || 5263 canvas['webkitRequestPointerLock'] || 5264 canvas['msRequestPointerLock'] || 5265 function(){}; 5266 canvas.exitPointerLock = document['exitPointerLock'] || 5267 document['mozExitPointerLock'] || 5268 document['webkitExitPointerLock'] || 5269 document['msExitPointerLock'] || 5270 function(){}; // no-op if function does not exist 5271 canvas.exitPointerLock = canvas.exitPointerLock.bind(document); 5272 5273 function pointerLockChange() { 5274 Browser.pointerLock = document['pointerLockElement'] === canvas || 5275 document['mozPointerLockElement'] === canvas || 5276 document['webkitPointerLockElement'] === canvas || 5277 document['msPointerLockElement'] === canvas; 5278 } 5279 5280 document.addEventListener('pointerlockchange', pointerLockChange, false); 5281 document.addEventListener('mozpointerlockchange', pointerLockChange, false); 5282 document.addEventListener('webkitpointerlockchange', pointerLockChange, false); 5283 document.addEventListener('mspointerlockchange', pointerLockChange, false); 5284 5285 if (Module['elementPointerLock']) { 5286 canvas.addEventListener("click", function(ev) { 5287 if (!Browser.pointerLock && canvas.requestPointerLock) { 5288 canvas.requestPointerLock(); 5289 ev.preventDefault(); 5290 } 5291 }, false); 5292 } 5293 },createContext:function (canvas, useWebGL, setInModule, webGLContextAttributes) { 5294 var ctx; 5295 var errorInfo = '?'; 5296 function onContextCreationError(event) { 5297 errorInfo = event.statusMessage || errorInfo; 5298 } 5299 try { 5300 if (useWebGL) { 5301 var contextAttributes = { 5302 antialias: false, 5303 alpha: false 5304 }; 5305 5306 if (webGLContextAttributes) { 5307 for (var attribute in webGLContextAttributes) { 5308 contextAttributes[attribute] = webGLContextAttributes[attribute]; 5309 } 5310 } 5311 5312 5313 canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false); 5314 try { 5315 ['experimental-webgl', 'webgl'].some(function(webglId) { 5316 return ctx = canvas.getContext(webglId, contextAttributes); 5317 }); 5318 } finally { 5319 canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false); 5320 } 5321 } else { 5322 ctx = canvas.getContext('2d'); 5323 } 5324 if (!ctx) throw ':('; 5325 } catch (e) { 5326 Module.print('Could not create canvas: ' + [errorInfo, e]); 5327 return null; 5328 } 5329 if (useWebGL) { 5330 // Set the background of the WebGL canvas to black 5331 canvas.style.backgroundColor = "black"; 5332 5333 // Warn on context loss 5334 canvas.addEventListener('webglcontextlost', function(event) { 5335 alert('WebGL context lost. You will need to reload the page.'); 5336 }, false); 5337 } 5338 if (setInModule) { 5339 GLctx = Module.ctx = ctx; 5340 Module.useWebGL = useWebGL; 5341 Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() }); 5342 Browser.init(); 5343 } 5344 return ctx; 5345 },destroyContext:function (canvas, useWebGL, setInModule) {},fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:function (lockPointer, resizeCanvas) { 5346 Browser.lockPointer = lockPointer; 5347 Browser.resizeCanvas = resizeCanvas; 5348 if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true; 5349 if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false; 5350 5351 var canvas = Module['canvas']; 5352 function fullScreenChange() { 5353 Browser.isFullScreen = false; 5354 var canvasContainer = canvas.parentNode; 5355 if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] || 5356 document['mozFullScreenElement'] || document['mozFullscreenElement'] || 5357 document['fullScreenElement'] || document['fullscreenElement'] || 5358 document['msFullScreenElement'] || document['msFullscreenElement'] || 5359 document['webkitCurrentFullScreenElement']) === canvasContainer) { 5360 canvas.cancelFullScreen = document['cancelFullScreen'] || 5361 document['mozCancelFullScreen'] || 5362 document['webkitCancelFullScreen'] || 5363 document['msExitFullscreen'] || 5364 document['exitFullscreen'] || 5365 function() {}; 5366 canvas.cancelFullScreen = canvas.cancelFullScreen.bind(document); 5367 if (Browser.lockPointer) canvas.requestPointerLock(); 5368 Browser.isFullScreen = true; 5369 if (Browser.resizeCanvas) Browser.setFullScreenCanvasSize(); 5370 } else { 5371 5372 // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen 5373 canvasContainer.parentNode.insertBefore(canvas, canvasContainer); 5374 canvasContainer.parentNode.removeChild(canvasContainer); 5375 5376 if (Browser.resizeCanvas) Browser.setWindowedCanvasSize(); 5377 } 5378 if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen); 5379 Browser.updateCanvasDimensions(canvas); 5380 } 5381 5382 if (!Browser.fullScreenHandlersInstalled) { 5383 Browser.fullScreenHandlersInstalled = true; 5384 document.addEventListener('fullscreenchange', fullScreenChange, false); 5385 document.addEventListener('mozfullscreenchange', fullScreenChange, false); 5386 document.addEventListener('webkitfullscreenchange', fullScreenChange, false); 5387 document.addEventListener('MSFullscreenChange', fullScreenChange, false); 5388 } 5389 5390 // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root 5391 var canvasContainer = document.createElement("div"); 5392 canvas.parentNode.insertBefore(canvasContainer, canvas); 5393 canvasContainer.appendChild(canvas); 5394 5395 // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size) 5396 canvasContainer.requestFullScreen = canvasContainer['requestFullScreen'] || 5397 canvasContainer['mozRequestFullScreen'] || 5398 canvasContainer['msRequestFullscreen'] || 5399 (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null); 5400 canvasContainer.requestFullScreen(); 5401 },requestAnimationFrame:function requestAnimationFrame(func) { 5402 if (typeof window === 'undefined') { // Provide fallback to setTimeout if window is undefined (e.g. in Node.js) 5403 setTimeout(func, 1000/60); 5404 } else { 5405 if (!window.requestAnimationFrame) { 5406 window.requestAnimationFrame = window['requestAnimationFrame'] || 5407 window['mozRequestAnimationFrame'] || 5408 window['webkitRequestAnimationFrame'] || 5409 window['msRequestAnimationFrame'] || 5410 window['oRequestAnimationFrame'] || 5411 window['setTimeout']; 5412 } 5413 window.requestAnimationFrame(func); 5414 } 5415 },safeCallback:function (func) { 5416 return function() { 5417 if (!ABORT) return func.apply(null, arguments); 5418 }; 5419 },safeRequestAnimationFrame:function (func) { 5420 return Browser.requestAnimationFrame(function() { 5421 if (!ABORT) func(); 5422 }); 5423 },safeSetTimeout:function (func, timeout) { 5424 return setTimeout(function() { 5425 if (!ABORT) func(); 5426 }, timeout); 5427 },safeSetInterval:function (func, timeout) { 5428 return setInterval(function() { 5429 if (!ABORT) func(); 5430 }, timeout); 5431 },getMimetype:function (name) { 5432 return { 5433 'jpg': 'image/jpeg', 5434 'jpeg': 'image/jpeg', 5435 'png': 'image/png', 5436 'bmp': 'image/bmp', 5437 'ogg': 'audio/ogg', 5438 'wav': 'audio/wav', 5439 'mp3': 'audio/mpeg' 5440 }[name.substr(name.lastIndexOf('.')+1)]; 5441 },getUserMedia:function (func) { 5442 if(!window.getUserMedia) { 5443 window.getUserMedia = navigator['getUserMedia'] || 5444 navigator['mozGetUserMedia']; 5445 } 5446 window.getUserMedia(func); 5447 },getMovementX:function (event) { 5448 return event['movementX'] || 5449 event['mozMovementX'] || 5450 event['webkitMovementX'] || 5451 0; 5452 },getMovementY:function (event) { 5453 return event['movementY'] || 5454 event['mozMovementY'] || 5455 event['webkitMovementY'] || 5456 0; 5457 },getMouseWheelDelta:function (event) { 5458 return Math.max(-1, Math.min(1, event.type === 'DOMMouseScroll' ? event.detail : -event.wheelDelta)); 5459 },mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,calculateMouseEvent:function (event) { // event should be mousemove, mousedown or mouseup 5460 if (Browser.pointerLock) { 5461 // When the pointer is locked, calculate the coordinates 5462 // based on the movement of the mouse. 5463 // Workaround for Firefox bug 764498 5464 if (event.type != 'mousemove' && 5465 ('mozMovementX' in event)) { 5466 Browser.mouseMovementX = Browser.mouseMovementY = 0; 5467 } else { 5468 Browser.mouseMovementX = Browser.getMovementX(event); 5469 Browser.mouseMovementY = Browser.getMovementY(event); 5470 } 5471 5472 // check if SDL is available 5473 if (typeof SDL != "undefined") { 5474 Browser.mouseX = SDL.mouseX + Browser.mouseMovementX; 5475 Browser.mouseY = SDL.mouseY + Browser.mouseMovementY; 5476 } else { 5477 // just add the mouse delta to the current absolut mouse position 5478 // FIXME: ideally this should be clamped against the canvas size and zero 5479 Browser.mouseX += Browser.mouseMovementX; 5480 Browser.mouseY += Browser.mouseMovementY; 5481 } 5482 } else { 5483 // Otherwise, calculate the movement based on the changes 5484 // in the coordinates. 5485 var rect = Module["canvas"].getBoundingClientRect(); 5486 var x, y; 5487 5488 // Neither .scrollX or .pageXOffset are defined in a spec, but 5489 // we prefer .scrollX because it is currently in a spec draft. 5490 // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/) 5491 var scrollX = ((typeof window.scrollX !== 'undefined') ? window.scrollX : window.pageXOffset); 5492 var scrollY = ((typeof window.scrollY !== 'undefined') ? window.scrollY : window.pageYOffset); 5493 if (event.type == 'touchstart' || 5494 event.type == 'touchend' || 5495 event.type == 'touchmove') { 5496 var t = event.touches.item(0); 5497 if (t) { 5498 x = t.pageX - (scrollX + rect.left); 5499 y = t.pageY - (scrollY + rect.top); 5500 } else { 5501 return; 5502 } 5503 } else { 5504 x = event.pageX - (scrollX + rect.left); 5505 y = event.pageY - (scrollY + rect.top); 5506 } 5507 5508 // the canvas might be CSS-scaled compared to its backbuffer; 5509 // SDL-using content will want mouse coordinates in terms 5510 // of backbuffer units. 5511 var cw = Module["canvas"].width; 5512 var ch = Module["canvas"].height; 5513 x = x * (cw / rect.width); 5514 y = y * (ch / rect.height); 5515 5516 Browser.mouseMovementX = x - Browser.mouseX; 5517 Browser.mouseMovementY = y - Browser.mouseY; 5518 Browser.mouseX = x; 5519 Browser.mouseY = y; 5520 } 5521 },xhrLoad:function (url, onload, onerror) { 5522 var xhr = new XMLHttpRequest(); 5523 xhr.open('GET', url, true); 5524 xhr.responseType = 'arraybuffer'; 5525 xhr.onload = function xhr_onload() { 5526 if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0 5527 onload(xhr.response); 5528 } else { 5529 onerror(); 5530 } 5531 }; 5532 xhr.onerror = onerror; 5533 xhr.send(null); 5534 },asyncLoad:function (url, onload, onerror, noRunDep) { 5535 Browser.xhrLoad(url, function(arrayBuffer) { 5536 assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).'); 5537 onload(new Uint8Array(arrayBuffer)); 5538 if (!noRunDep) removeRunDependency('al ' + url); 5539 }, function(event) { 5540 if (onerror) { 5541 onerror(); 5542 } else { 5543 throw 'Loading data file "' + url + '" failed.'; 5544 } 5545 }); 5546 if (!noRunDep) addRunDependency('al ' + url); 5547 },resizeListeners:[],updateResizeListeners:function () { 5548 var canvas = Module['canvas']; 5549 Browser.resizeListeners.forEach(function(listener) { 5550 listener(canvas.width, canvas.height); 5551 }); 5552 },setCanvasSize:function (width, height, noUpdates) { 5553 var canvas = Module['canvas']; 5554 Browser.updateCanvasDimensions(canvas, width, height); 5555 if (!noUpdates) Browser.updateResizeListeners(); 5556 },windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:function () { 5557 // check if SDL is available 5558 if (typeof SDL != "undefined") { 5559 var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]; 5560 flags = flags | 0x00800000; // set SDL_FULLSCREEN flag 5561 HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags 5562 } 5563 Browser.updateResizeListeners(); 5564 },setWindowedCanvasSize:function () { 5565 // check if SDL is available 5566 if (typeof SDL != "undefined") { 5567 var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]; 5568 flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag 5569 HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags 5570 } 5571 Browser.updateResizeListeners(); 5572 },updateCanvasDimensions:function (canvas, wNative, hNative) { 5573 if (wNative && hNative) { 5574 canvas.widthNative = wNative; 5575 canvas.heightNative = hNative; 5576 } else { 5577 wNative = canvas.widthNative; 5578 hNative = canvas.heightNative; 5579 } 5580 var w = wNative; 5581 var h = hNative; 5582 if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) { 5583 if (w/h < Module['forcedAspectRatio']) { 5584 w = Math.round(h * Module['forcedAspectRatio']); 5585 } else { 5586 h = Math.round(w / Module['forcedAspectRatio']); 5587 } 5588 } 5589 if (((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] || 5590 document['mozFullScreenElement'] || document['mozFullscreenElement'] || 5591 document['fullScreenElement'] || document['fullscreenElement'] || 5592 document['msFullScreenElement'] || document['msFullscreenElement'] || 5593 document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) { 5594 var factor = Math.min(screen.width / w, screen.height / h); 5595 w = Math.round(w * factor); 5596 h = Math.round(h * factor); 5597 } 5598 if (Browser.resizeCanvas) { 5599 if (canvas.width != w) canvas.width = w; 5600 if (canvas.height != h) canvas.height = h; 5601 if (typeof canvas.style != 'undefined') { 5602 canvas.style.removeProperty( "width"); 5603 canvas.style.removeProperty("height"); 5604 } 5605 } else { 5606 if (canvas.width != wNative) canvas.width = wNative; 5607 if (canvas.height != hNative) canvas.height = hNative; 5608 if (typeof canvas.style != 'undefined') { 5609 if (w != wNative || h != hNative) { 5610 canvas.style.setProperty( "width", w + "px", "important"); 5611 canvas.style.setProperty("height", h + "px", "important"); 5612 } else { 5613 canvas.style.removeProperty( "width"); 5614 canvas.style.removeProperty("height"); 5615 } 5616 } 5617 } 5618 }}; 5619 5620 function _time(ptr) { 5621 var ret = Math.floor(Date.now()/1000); 5622 if (ptr) { 5623 HEAP32[((ptr)>>2)]=ret; 5624 } 5625 return ret; 5626 } 5627 5628 5629 5630 function _emscripten_memcpy_big(dest, src, num) { 5631 HEAPU8.set(HEAPU8.subarray(src, src+num), dest); 5632 return dest; 5633 } 5634 Module["_memcpy"] = _memcpy; 5635FS.staticInit();__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });__ATMAIN__.push({ func: function() { FS.ignorePermissions = false } });__ATEXIT__.push({ func: function() { FS.quit() } });Module["FS_createFolder"] = FS.createFolder;Module["FS_createPath"] = FS.createPath;Module["FS_createDataFile"] = FS.createDataFile;Module["FS_createPreloadedFile"] = FS.createPreloadedFile;Module["FS_createLazyFile"] = FS.createLazyFile;Module["FS_createLink"] = FS.createLink;Module["FS_createDevice"] = FS.createDevice; 5636___errno_state = Runtime.staticAlloc(4); HEAP32[((___errno_state)>>2)]=0; 5637__ATINIT__.unshift({ func: function() { TTY.init() } });__ATEXIT__.push({ func: function() { TTY.shutdown() } });TTY.utf8 = new Runtime.UTF8Processor(); 5638if (ENVIRONMENT_IS_NODE) { var fs = require("fs"); NODEFS.staticInit(); } 5639__ATINIT__.push({ func: function() { SOCKFS.root = FS.mount(SOCKFS, {}, null); } }); 5640_fputc.ret = allocate([0], "i8", ALLOC_STATIC); 5641Module["requestFullScreen"] = function Module_requestFullScreen(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) }; 5642 Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) }; 5643 Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) }; 5644 Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() }; 5645 Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() }; 5646 Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() } 5647STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP); 5648 5649staticSealed = true; // seal the static portion of memory 5650 5651STACK_MAX = STACK_BASE + 5242880; 5652 5653DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX); 5654 5655assert(DYNAMIC_BASE < TOTAL_MEMORY, "TOTAL_MEMORY not big enough for stack"); 5656 5657 5658var Math_min = Math.min; 5659function asmPrintInt(x, y) { 5660 Module.print('int ' + x + ',' + y);// + ' ' + new Error().stack); 5661} 5662function asmPrintFloat(x, y) { 5663 Module.print('float ' + x + ',' + y);// + ' ' + new Error().stack); 5664} 5665// EMSCRIPTEN_START_ASM 5666var asm = (function(global, env, buffer) { 5667 'use asm'; 5668 var HEAP8 = new global.Int8Array(buffer); 5669 var HEAP16 = new global.Int16Array(buffer); 5670 var HEAP32 = new global.Int32Array(buffer); 5671 var HEAPU8 = new global.Uint8Array(buffer); 5672 var HEAPU16 = new global.Uint16Array(buffer); 5673 var HEAPU32 = new global.Uint32Array(buffer); 5674 var HEAPF32 = new global.Float32Array(buffer); 5675 var HEAPF64 = new global.Float64Array(buffer); 5676 5677 var STACKTOP=env.STACKTOP|0; 5678 var STACK_MAX=env.STACK_MAX|0; 5679 var tempDoublePtr=env.tempDoublePtr|0; 5680 var ABORT=env.ABORT|0; 5681 5682 var __THREW__ = 0; 5683 var threwValue = 0; 5684 var setjmpId = 0; 5685 var undef = 0; 5686 var nan = +env.NaN, inf = +env.Infinity; 5687 var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0; 5688 5689 var tempRet0 = 0; 5690 var tempRet1 = 0; 5691 var tempRet2 = 0; 5692 var tempRet3 = 0; 5693 var tempRet4 = 0; 5694 var tempRet5 = 0; 5695 var tempRet6 = 0; 5696 var tempRet7 = 0; 5697 var tempRet8 = 0; 5698 var tempRet9 = 0; 5699 var Math_floor=global.Math.floor; 5700 var Math_abs=global.Math.abs; 5701 var Math_sqrt=global.Math.sqrt; 5702 var Math_pow=global.Math.pow; 5703 var Math_cos=global.Math.cos; 5704 var Math_sin=global.Math.sin; 5705 var Math_tan=global.Math.tan; 5706 var Math_acos=global.Math.acos; 5707 var Math_asin=global.Math.asin; 5708 var Math_atan=global.Math.atan; 5709 var Math_atan2=global.Math.atan2; 5710 var Math_exp=global.Math.exp; 5711 var Math_log=global.Math.log; 5712 var Math_ceil=global.Math.ceil; 5713 var Math_imul=global.Math.imul; 5714 var abort=env.abort; 5715 var assert=env.assert; 5716 var asmPrintInt=env.asmPrintInt; 5717 var asmPrintFloat=env.asmPrintFloat; 5718 var Math_min=env.min; 5719 var _fflush=env._fflush; 5720 var _emscripten_memcpy_big=env._emscripten_memcpy_big; 5721 var _putchar=env._putchar; 5722 var _fputc=env._fputc; 5723 var _send=env._send; 5724 var _pwrite=env._pwrite; 5725 var _abort=env._abort; 5726 var __reallyNegative=env.__reallyNegative; 5727 var _fwrite=env._fwrite; 5728 var _sbrk=env._sbrk; 5729 var _mkport=env._mkport; 5730 var _fprintf=env._fprintf; 5731 var ___setErrNo=env.___setErrNo; 5732 var __formatString=env.__formatString; 5733 var _fileno=env._fileno; 5734 var _printf=env._printf; 5735 var _time=env._time; 5736 var _sysconf=env._sysconf; 5737 var _write=env._write; 5738 var ___errno_location=env.___errno_location; 5739 var tempFloat = 0.0; 5740 5741// EMSCRIPTEN_START_FUNCS 5742function _malloc(i12) { 5743 i12 = i12 | 0; 5744 var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0; 5745 i1 = STACKTOP; 5746 do { 5747 if (i12 >>> 0 < 245) { 5748 if (i12 >>> 0 < 11) { 5749 i12 = 16; 5750 } else { 5751 i12 = i12 + 11 & -8; 5752 } 5753 i20 = i12 >>> 3; 5754 i18 = HEAP32[14] | 0; 5755 i21 = i18 >>> i20; 5756 if ((i21 & 3 | 0) != 0) { 5757 i6 = (i21 & 1 ^ 1) + i20 | 0; 5758 i5 = i6 << 1; 5759 i3 = 96 + (i5 << 2) | 0; 5760 i5 = 96 + (i5 + 2 << 2) | 0; 5761 i7 = HEAP32[i5 >> 2] | 0; 5762 i2 = i7 + 8 | 0; 5763 i4 = HEAP32[i2 >> 2] | 0; 5764 do { 5765 if ((i3 | 0) != (i4 | 0)) { 5766 if (i4 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 5767 _abort(); 5768 } 5769 i8 = i4 + 12 | 0; 5770 if ((HEAP32[i8 >> 2] | 0) == (i7 | 0)) { 5771 HEAP32[i8 >> 2] = i3; 5772 HEAP32[i5 >> 2] = i4; 5773 break; 5774 } else { 5775 _abort(); 5776 } 5777 } else { 5778 HEAP32[14] = i18 & ~(1 << i6); 5779 } 5780 } while (0); 5781 i32 = i6 << 3; 5782 HEAP32[i7 + 4 >> 2] = i32 | 3; 5783 i32 = i7 + (i32 | 4) | 0; 5784 HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1; 5785 i32 = i2; 5786 STACKTOP = i1; 5787 return i32 | 0; 5788 } 5789 if (i12 >>> 0 > (HEAP32[64 >> 2] | 0) >>> 0) { 5790 if ((i21 | 0) != 0) { 5791 i7 = 2 << i20; 5792 i7 = i21 << i20 & (i7 | 0 - i7); 5793 i7 = (i7 & 0 - i7) + -1 | 0; 5794 i2 = i7 >>> 12 & 16; 5795 i7 = i7 >>> i2; 5796 i6 = i7 >>> 5 & 8; 5797 i7 = i7 >>> i6; 5798 i5 = i7 >>> 2 & 4; 5799 i7 = i7 >>> i5; 5800 i4 = i7 >>> 1 & 2; 5801 i7 = i7 >>> i4; 5802 i3 = i7 >>> 1 & 1; 5803 i3 = (i6 | i2 | i5 | i4 | i3) + (i7 >>> i3) | 0; 5804 i7 = i3 << 1; 5805 i4 = 96 + (i7 << 2) | 0; 5806 i7 = 96 + (i7 + 2 << 2) | 0; 5807 i5 = HEAP32[i7 >> 2] | 0; 5808 i2 = i5 + 8 | 0; 5809 i6 = HEAP32[i2 >> 2] | 0; 5810 do { 5811 if ((i4 | 0) != (i6 | 0)) { 5812 if (i6 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 5813 _abort(); 5814 } 5815 i8 = i6 + 12 | 0; 5816 if ((HEAP32[i8 >> 2] | 0) == (i5 | 0)) { 5817 HEAP32[i8 >> 2] = i4; 5818 HEAP32[i7 >> 2] = i6; 5819 break; 5820 } else { 5821 _abort(); 5822 } 5823 } else { 5824 HEAP32[14] = i18 & ~(1 << i3); 5825 } 5826 } while (0); 5827 i6 = i3 << 3; 5828 i4 = i6 - i12 | 0; 5829 HEAP32[i5 + 4 >> 2] = i12 | 3; 5830 i3 = i5 + i12 | 0; 5831 HEAP32[i5 + (i12 | 4) >> 2] = i4 | 1; 5832 HEAP32[i5 + i6 >> 2] = i4; 5833 i6 = HEAP32[64 >> 2] | 0; 5834 if ((i6 | 0) != 0) { 5835 i5 = HEAP32[76 >> 2] | 0; 5836 i8 = i6 >>> 3; 5837 i9 = i8 << 1; 5838 i6 = 96 + (i9 << 2) | 0; 5839 i7 = HEAP32[14] | 0; 5840 i8 = 1 << i8; 5841 if ((i7 & i8 | 0) != 0) { 5842 i7 = 96 + (i9 + 2 << 2) | 0; 5843 i8 = HEAP32[i7 >> 2] | 0; 5844 if (i8 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 5845 _abort(); 5846 } else { 5847 i28 = i7; 5848 i27 = i8; 5849 } 5850 } else { 5851 HEAP32[14] = i7 | i8; 5852 i28 = 96 + (i9 + 2 << 2) | 0; 5853 i27 = i6; 5854 } 5855 HEAP32[i28 >> 2] = i5; 5856 HEAP32[i27 + 12 >> 2] = i5; 5857 HEAP32[i5 + 8 >> 2] = i27; 5858 HEAP32[i5 + 12 >> 2] = i6; 5859 } 5860 HEAP32[64 >> 2] = i4; 5861 HEAP32[76 >> 2] = i3; 5862 i32 = i2; 5863 STACKTOP = i1; 5864 return i32 | 0; 5865 } 5866 i18 = HEAP32[60 >> 2] | 0; 5867 if ((i18 | 0) != 0) { 5868 i2 = (i18 & 0 - i18) + -1 | 0; 5869 i31 = i2 >>> 12 & 16; 5870 i2 = i2 >>> i31; 5871 i30 = i2 >>> 5 & 8; 5872 i2 = i2 >>> i30; 5873 i32 = i2 >>> 2 & 4; 5874 i2 = i2 >>> i32; 5875 i6 = i2 >>> 1 & 2; 5876 i2 = i2 >>> i6; 5877 i3 = i2 >>> 1 & 1; 5878 i3 = HEAP32[360 + ((i30 | i31 | i32 | i6 | i3) + (i2 >>> i3) << 2) >> 2] | 0; 5879 i2 = (HEAP32[i3 + 4 >> 2] & -8) - i12 | 0; 5880 i6 = i3; 5881 while (1) { 5882 i5 = HEAP32[i6 + 16 >> 2] | 0; 5883 if ((i5 | 0) == 0) { 5884 i5 = HEAP32[i6 + 20 >> 2] | 0; 5885 if ((i5 | 0) == 0) { 5886 break; 5887 } 5888 } 5889 i6 = (HEAP32[i5 + 4 >> 2] & -8) - i12 | 0; 5890 i4 = i6 >>> 0 < i2 >>> 0; 5891 i2 = i4 ? i6 : i2; 5892 i6 = i5; 5893 i3 = i4 ? i5 : i3; 5894 } 5895 i6 = HEAP32[72 >> 2] | 0; 5896 if (i3 >>> 0 < i6 >>> 0) { 5897 _abort(); 5898 } 5899 i4 = i3 + i12 | 0; 5900 if (!(i3 >>> 0 < i4 >>> 0)) { 5901 _abort(); 5902 } 5903 i5 = HEAP32[i3 + 24 >> 2] | 0; 5904 i7 = HEAP32[i3 + 12 >> 2] | 0; 5905 do { 5906 if ((i7 | 0) == (i3 | 0)) { 5907 i8 = i3 + 20 | 0; 5908 i7 = HEAP32[i8 >> 2] | 0; 5909 if ((i7 | 0) == 0) { 5910 i8 = i3 + 16 | 0; 5911 i7 = HEAP32[i8 >> 2] | 0; 5912 if ((i7 | 0) == 0) { 5913 i26 = 0; 5914 break; 5915 } 5916 } 5917 while (1) { 5918 i10 = i7 + 20 | 0; 5919 i9 = HEAP32[i10 >> 2] | 0; 5920 if ((i9 | 0) != 0) { 5921 i7 = i9; 5922 i8 = i10; 5923 continue; 5924 } 5925 i10 = i7 + 16 | 0; 5926 i9 = HEAP32[i10 >> 2] | 0; 5927 if ((i9 | 0) == 0) { 5928 break; 5929 } else { 5930 i7 = i9; 5931 i8 = i10; 5932 } 5933 } 5934 if (i8 >>> 0 < i6 >>> 0) { 5935 _abort(); 5936 } else { 5937 HEAP32[i8 >> 2] = 0; 5938 i26 = i7; 5939 break; 5940 } 5941 } else { 5942 i8 = HEAP32[i3 + 8 >> 2] | 0; 5943 if (i8 >>> 0 < i6 >>> 0) { 5944 _abort(); 5945 } 5946 i6 = i8 + 12 | 0; 5947 if ((HEAP32[i6 >> 2] | 0) != (i3 | 0)) { 5948 _abort(); 5949 } 5950 i9 = i7 + 8 | 0; 5951 if ((HEAP32[i9 >> 2] | 0) == (i3 | 0)) { 5952 HEAP32[i6 >> 2] = i7; 5953 HEAP32[i9 >> 2] = i8; 5954 i26 = i7; 5955 break; 5956 } else { 5957 _abort(); 5958 } 5959 } 5960 } while (0); 5961 do { 5962 if ((i5 | 0) != 0) { 5963 i7 = HEAP32[i3 + 28 >> 2] | 0; 5964 i6 = 360 + (i7 << 2) | 0; 5965 if ((i3 | 0) == (HEAP32[i6 >> 2] | 0)) { 5966 HEAP32[i6 >> 2] = i26; 5967 if ((i26 | 0) == 0) { 5968 HEAP32[60 >> 2] = HEAP32[60 >> 2] & ~(1 << i7); 5969 break; 5970 } 5971 } else { 5972 if (i5 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 5973 _abort(); 5974 } 5975 i6 = i5 + 16 | 0; 5976 if ((HEAP32[i6 >> 2] | 0) == (i3 | 0)) { 5977 HEAP32[i6 >> 2] = i26; 5978 } else { 5979 HEAP32[i5 + 20 >> 2] = i26; 5980 } 5981 if ((i26 | 0) == 0) { 5982 break; 5983 } 5984 } 5985 if (i26 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 5986 _abort(); 5987 } 5988 HEAP32[i26 + 24 >> 2] = i5; 5989 i5 = HEAP32[i3 + 16 >> 2] | 0; 5990 do { 5991 if ((i5 | 0) != 0) { 5992 if (i5 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 5993 _abort(); 5994 } else { 5995 HEAP32[i26 + 16 >> 2] = i5; 5996 HEAP32[i5 + 24 >> 2] = i26; 5997 break; 5998 } 5999 } 6000 } while (0); 6001 i5 = HEAP32[i3 + 20 >> 2] | 0; 6002 if ((i5 | 0) != 0) { 6003 if (i5 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6004 _abort(); 6005 } else { 6006 HEAP32[i26 + 20 >> 2] = i5; 6007 HEAP32[i5 + 24 >> 2] = i26; 6008 break; 6009 } 6010 } 6011 } 6012 } while (0); 6013 if (i2 >>> 0 < 16) { 6014 i32 = i2 + i12 | 0; 6015 HEAP32[i3 + 4 >> 2] = i32 | 3; 6016 i32 = i3 + (i32 + 4) | 0; 6017 HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1; 6018 } else { 6019 HEAP32[i3 + 4 >> 2] = i12 | 3; 6020 HEAP32[i3 + (i12 | 4) >> 2] = i2 | 1; 6021 HEAP32[i3 + (i2 + i12) >> 2] = i2; 6022 i6 = HEAP32[64 >> 2] | 0; 6023 if ((i6 | 0) != 0) { 6024 i5 = HEAP32[76 >> 2] | 0; 6025 i8 = i6 >>> 3; 6026 i9 = i8 << 1; 6027 i6 = 96 + (i9 << 2) | 0; 6028 i7 = HEAP32[14] | 0; 6029 i8 = 1 << i8; 6030 if ((i7 & i8 | 0) != 0) { 6031 i7 = 96 + (i9 + 2 << 2) | 0; 6032 i8 = HEAP32[i7 >> 2] | 0; 6033 if (i8 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6034 _abort(); 6035 } else { 6036 i25 = i7; 6037 i24 = i8; 6038 } 6039 } else { 6040 HEAP32[14] = i7 | i8; 6041 i25 = 96 + (i9 + 2 << 2) | 0; 6042 i24 = i6; 6043 } 6044 HEAP32[i25 >> 2] = i5; 6045 HEAP32[i24 + 12 >> 2] = i5; 6046 HEAP32[i5 + 8 >> 2] = i24; 6047 HEAP32[i5 + 12 >> 2] = i6; 6048 } 6049 HEAP32[64 >> 2] = i2; 6050 HEAP32[76 >> 2] = i4; 6051 } 6052 i32 = i3 + 8 | 0; 6053 STACKTOP = i1; 6054 return i32 | 0; 6055 } 6056 } 6057 } else { 6058 if (!(i12 >>> 0 > 4294967231)) { 6059 i24 = i12 + 11 | 0; 6060 i12 = i24 & -8; 6061 i26 = HEAP32[60 >> 2] | 0; 6062 if ((i26 | 0) != 0) { 6063 i25 = 0 - i12 | 0; 6064 i24 = i24 >>> 8; 6065 if ((i24 | 0) != 0) { 6066 if (i12 >>> 0 > 16777215) { 6067 i27 = 31; 6068 } else { 6069 i31 = (i24 + 1048320 | 0) >>> 16 & 8; 6070 i32 = i24 << i31; 6071 i30 = (i32 + 520192 | 0) >>> 16 & 4; 6072 i32 = i32 << i30; 6073 i27 = (i32 + 245760 | 0) >>> 16 & 2; 6074 i27 = 14 - (i30 | i31 | i27) + (i32 << i27 >>> 15) | 0; 6075 i27 = i12 >>> (i27 + 7 | 0) & 1 | i27 << 1; 6076 } 6077 } else { 6078 i27 = 0; 6079 } 6080 i30 = HEAP32[360 + (i27 << 2) >> 2] | 0; 6081 L126 : do { 6082 if ((i30 | 0) == 0) { 6083 i29 = 0; 6084 i24 = 0; 6085 } else { 6086 if ((i27 | 0) == 31) { 6087 i24 = 0; 6088 } else { 6089 i24 = 25 - (i27 >>> 1) | 0; 6090 } 6091 i29 = 0; 6092 i28 = i12 << i24; 6093 i24 = 0; 6094 while (1) { 6095 i32 = HEAP32[i30 + 4 >> 2] & -8; 6096 i31 = i32 - i12 | 0; 6097 if (i31 >>> 0 < i25 >>> 0) { 6098 if ((i32 | 0) == (i12 | 0)) { 6099 i25 = i31; 6100 i29 = i30; 6101 i24 = i30; 6102 break L126; 6103 } else { 6104 i25 = i31; 6105 i24 = i30; 6106 } 6107 } 6108 i31 = HEAP32[i30 + 20 >> 2] | 0; 6109 i30 = HEAP32[i30 + (i28 >>> 31 << 2) + 16 >> 2] | 0; 6110 i29 = (i31 | 0) == 0 | (i31 | 0) == (i30 | 0) ? i29 : i31; 6111 if ((i30 | 0) == 0) { 6112 break; 6113 } else { 6114 i28 = i28 << 1; 6115 } 6116 } 6117 } 6118 } while (0); 6119 if ((i29 | 0) == 0 & (i24 | 0) == 0) { 6120 i32 = 2 << i27; 6121 i26 = i26 & (i32 | 0 - i32); 6122 if ((i26 | 0) == 0) { 6123 break; 6124 } 6125 i32 = (i26 & 0 - i26) + -1 | 0; 6126 i28 = i32 >>> 12 & 16; 6127 i32 = i32 >>> i28; 6128 i27 = i32 >>> 5 & 8; 6129 i32 = i32 >>> i27; 6130 i30 = i32 >>> 2 & 4; 6131 i32 = i32 >>> i30; 6132 i31 = i32 >>> 1 & 2; 6133 i32 = i32 >>> i31; 6134 i29 = i32 >>> 1 & 1; 6135 i29 = HEAP32[360 + ((i27 | i28 | i30 | i31 | i29) + (i32 >>> i29) << 2) >> 2] | 0; 6136 } 6137 if ((i29 | 0) != 0) { 6138 while (1) { 6139 i27 = (HEAP32[i29 + 4 >> 2] & -8) - i12 | 0; 6140 i26 = i27 >>> 0 < i25 >>> 0; 6141 i25 = i26 ? i27 : i25; 6142 i24 = i26 ? i29 : i24; 6143 i26 = HEAP32[i29 + 16 >> 2] | 0; 6144 if ((i26 | 0) != 0) { 6145 i29 = i26; 6146 continue; 6147 } 6148 i29 = HEAP32[i29 + 20 >> 2] | 0; 6149 if ((i29 | 0) == 0) { 6150 break; 6151 } 6152 } 6153 } 6154 if ((i24 | 0) != 0 ? i25 >>> 0 < ((HEAP32[64 >> 2] | 0) - i12 | 0) >>> 0 : 0) { 6155 i4 = HEAP32[72 >> 2] | 0; 6156 if (i24 >>> 0 < i4 >>> 0) { 6157 _abort(); 6158 } 6159 i2 = i24 + i12 | 0; 6160 if (!(i24 >>> 0 < i2 >>> 0)) { 6161 _abort(); 6162 } 6163 i3 = HEAP32[i24 + 24 >> 2] | 0; 6164 i6 = HEAP32[i24 + 12 >> 2] | 0; 6165 do { 6166 if ((i6 | 0) == (i24 | 0)) { 6167 i6 = i24 + 20 | 0; 6168 i5 = HEAP32[i6 >> 2] | 0; 6169 if ((i5 | 0) == 0) { 6170 i6 = i24 + 16 | 0; 6171 i5 = HEAP32[i6 >> 2] | 0; 6172 if ((i5 | 0) == 0) { 6173 i22 = 0; 6174 break; 6175 } 6176 } 6177 while (1) { 6178 i8 = i5 + 20 | 0; 6179 i7 = HEAP32[i8 >> 2] | 0; 6180 if ((i7 | 0) != 0) { 6181 i5 = i7; 6182 i6 = i8; 6183 continue; 6184 } 6185 i7 = i5 + 16 | 0; 6186 i8 = HEAP32[i7 >> 2] | 0; 6187 if ((i8 | 0) == 0) { 6188 break; 6189 } else { 6190 i5 = i8; 6191 i6 = i7; 6192 } 6193 } 6194 if (i6 >>> 0 < i4 >>> 0) { 6195 _abort(); 6196 } else { 6197 HEAP32[i6 >> 2] = 0; 6198 i22 = i5; 6199 break; 6200 } 6201 } else { 6202 i5 = HEAP32[i24 + 8 >> 2] | 0; 6203 if (i5 >>> 0 < i4 >>> 0) { 6204 _abort(); 6205 } 6206 i7 = i5 + 12 | 0; 6207 if ((HEAP32[i7 >> 2] | 0) != (i24 | 0)) { 6208 _abort(); 6209 } 6210 i4 = i6 + 8 | 0; 6211 if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) { 6212 HEAP32[i7 >> 2] = i6; 6213 HEAP32[i4 >> 2] = i5; 6214 i22 = i6; 6215 break; 6216 } else { 6217 _abort(); 6218 } 6219 } 6220 } while (0); 6221 do { 6222 if ((i3 | 0) != 0) { 6223 i4 = HEAP32[i24 + 28 >> 2] | 0; 6224 i5 = 360 + (i4 << 2) | 0; 6225 if ((i24 | 0) == (HEAP32[i5 >> 2] | 0)) { 6226 HEAP32[i5 >> 2] = i22; 6227 if ((i22 | 0) == 0) { 6228 HEAP32[60 >> 2] = HEAP32[60 >> 2] & ~(1 << i4); 6229 break; 6230 } 6231 } else { 6232 if (i3 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6233 _abort(); 6234 } 6235 i4 = i3 + 16 | 0; 6236 if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) { 6237 HEAP32[i4 >> 2] = i22; 6238 } else { 6239 HEAP32[i3 + 20 >> 2] = i22; 6240 } 6241 if ((i22 | 0) == 0) { 6242 break; 6243 } 6244 } 6245 if (i22 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6246 _abort(); 6247 } 6248 HEAP32[i22 + 24 >> 2] = i3; 6249 i3 = HEAP32[i24 + 16 >> 2] | 0; 6250 do { 6251 if ((i3 | 0) != 0) { 6252 if (i3 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6253 _abort(); 6254 } else { 6255 HEAP32[i22 + 16 >> 2] = i3; 6256 HEAP32[i3 + 24 >> 2] = i22; 6257 break; 6258 } 6259 } 6260 } while (0); 6261 i3 = HEAP32[i24 + 20 >> 2] | 0; 6262 if ((i3 | 0) != 0) { 6263 if (i3 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6264 _abort(); 6265 } else { 6266 HEAP32[i22 + 20 >> 2] = i3; 6267 HEAP32[i3 + 24 >> 2] = i22; 6268 break; 6269 } 6270 } 6271 } 6272 } while (0); 6273 L204 : do { 6274 if (!(i25 >>> 0 < 16)) { 6275 HEAP32[i24 + 4 >> 2] = i12 | 3; 6276 HEAP32[i24 + (i12 | 4) >> 2] = i25 | 1; 6277 HEAP32[i24 + (i25 + i12) >> 2] = i25; 6278 i4 = i25 >>> 3; 6279 if (i25 >>> 0 < 256) { 6280 i6 = i4 << 1; 6281 i3 = 96 + (i6 << 2) | 0; 6282 i5 = HEAP32[14] | 0; 6283 i4 = 1 << i4; 6284 if ((i5 & i4 | 0) != 0) { 6285 i5 = 96 + (i6 + 2 << 2) | 0; 6286 i4 = HEAP32[i5 >> 2] | 0; 6287 if (i4 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6288 _abort(); 6289 } else { 6290 i21 = i5; 6291 i20 = i4; 6292 } 6293 } else { 6294 HEAP32[14] = i5 | i4; 6295 i21 = 96 + (i6 + 2 << 2) | 0; 6296 i20 = i3; 6297 } 6298 HEAP32[i21 >> 2] = i2; 6299 HEAP32[i20 + 12 >> 2] = i2; 6300 HEAP32[i24 + (i12 + 8) >> 2] = i20; 6301 HEAP32[i24 + (i12 + 12) >> 2] = i3; 6302 break; 6303 } 6304 i3 = i25 >>> 8; 6305 if ((i3 | 0) != 0) { 6306 if (i25 >>> 0 > 16777215) { 6307 i3 = 31; 6308 } else { 6309 i31 = (i3 + 1048320 | 0) >>> 16 & 8; 6310 i32 = i3 << i31; 6311 i30 = (i32 + 520192 | 0) >>> 16 & 4; 6312 i32 = i32 << i30; 6313 i3 = (i32 + 245760 | 0) >>> 16 & 2; 6314 i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0; 6315 i3 = i25 >>> (i3 + 7 | 0) & 1 | i3 << 1; 6316 } 6317 } else { 6318 i3 = 0; 6319 } 6320 i6 = 360 + (i3 << 2) | 0; 6321 HEAP32[i24 + (i12 + 28) >> 2] = i3; 6322 HEAP32[i24 + (i12 + 20) >> 2] = 0; 6323 HEAP32[i24 + (i12 + 16) >> 2] = 0; 6324 i4 = HEAP32[60 >> 2] | 0; 6325 i5 = 1 << i3; 6326 if ((i4 & i5 | 0) == 0) { 6327 HEAP32[60 >> 2] = i4 | i5; 6328 HEAP32[i6 >> 2] = i2; 6329 HEAP32[i24 + (i12 + 24) >> 2] = i6; 6330 HEAP32[i24 + (i12 + 12) >> 2] = i2; 6331 HEAP32[i24 + (i12 + 8) >> 2] = i2; 6332 break; 6333 } 6334 i4 = HEAP32[i6 >> 2] | 0; 6335 if ((i3 | 0) == 31) { 6336 i3 = 0; 6337 } else { 6338 i3 = 25 - (i3 >>> 1) | 0; 6339 } 6340 L225 : do { 6341 if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i25 | 0)) { 6342 i3 = i25 << i3; 6343 while (1) { 6344 i6 = i4 + (i3 >>> 31 << 2) + 16 | 0; 6345 i5 = HEAP32[i6 >> 2] | 0; 6346 if ((i5 | 0) == 0) { 6347 break; 6348 } 6349 if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i25 | 0)) { 6350 i18 = i5; 6351 break L225; 6352 } else { 6353 i3 = i3 << 1; 6354 i4 = i5; 6355 } 6356 } 6357 if (i6 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6358 _abort(); 6359 } else { 6360 HEAP32[i6 >> 2] = i2; 6361 HEAP32[i24 + (i12 + 24) >> 2] = i4; 6362 HEAP32[i24 + (i12 + 12) >> 2] = i2; 6363 HEAP32[i24 + (i12 + 8) >> 2] = i2; 6364 break L204; 6365 } 6366 } else { 6367 i18 = i4; 6368 } 6369 } while (0); 6370 i4 = i18 + 8 | 0; 6371 i3 = HEAP32[i4 >> 2] | 0; 6372 i5 = HEAP32[72 >> 2] | 0; 6373 if (i18 >>> 0 < i5 >>> 0) { 6374 _abort(); 6375 } 6376 if (i3 >>> 0 < i5 >>> 0) { 6377 _abort(); 6378 } else { 6379 HEAP32[i3 + 12 >> 2] = i2; 6380 HEAP32[i4 >> 2] = i2; 6381 HEAP32[i24 + (i12 + 8) >> 2] = i3; 6382 HEAP32[i24 + (i12 + 12) >> 2] = i18; 6383 HEAP32[i24 + (i12 + 24) >> 2] = 0; 6384 break; 6385 } 6386 } else { 6387 i32 = i25 + i12 | 0; 6388 HEAP32[i24 + 4 >> 2] = i32 | 3; 6389 i32 = i24 + (i32 + 4) | 0; 6390 HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1; 6391 } 6392 } while (0); 6393 i32 = i24 + 8 | 0; 6394 STACKTOP = i1; 6395 return i32 | 0; 6396 } 6397 } 6398 } else { 6399 i12 = -1; 6400 } 6401 } 6402 } while (0); 6403 i18 = HEAP32[64 >> 2] | 0; 6404 if (!(i12 >>> 0 > i18 >>> 0)) { 6405 i3 = i18 - i12 | 0; 6406 i2 = HEAP32[76 >> 2] | 0; 6407 if (i3 >>> 0 > 15) { 6408 HEAP32[76 >> 2] = i2 + i12; 6409 HEAP32[64 >> 2] = i3; 6410 HEAP32[i2 + (i12 + 4) >> 2] = i3 | 1; 6411 HEAP32[i2 + i18 >> 2] = i3; 6412 HEAP32[i2 + 4 >> 2] = i12 | 3; 6413 } else { 6414 HEAP32[64 >> 2] = 0; 6415 HEAP32[76 >> 2] = 0; 6416 HEAP32[i2 + 4 >> 2] = i18 | 3; 6417 i32 = i2 + (i18 + 4) | 0; 6418 HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1; 6419 } 6420 i32 = i2 + 8 | 0; 6421 STACKTOP = i1; 6422 return i32 | 0; 6423 } 6424 i18 = HEAP32[68 >> 2] | 0; 6425 if (i12 >>> 0 < i18 >>> 0) { 6426 i31 = i18 - i12 | 0; 6427 HEAP32[68 >> 2] = i31; 6428 i32 = HEAP32[80 >> 2] | 0; 6429 HEAP32[80 >> 2] = i32 + i12; 6430 HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1; 6431 HEAP32[i32 + 4 >> 2] = i12 | 3; 6432 i32 = i32 + 8 | 0; 6433 STACKTOP = i1; 6434 return i32 | 0; 6435 } 6436 do { 6437 if ((HEAP32[132] | 0) == 0) { 6438 i18 = _sysconf(30) | 0; 6439 if ((i18 + -1 & i18 | 0) == 0) { 6440 HEAP32[536 >> 2] = i18; 6441 HEAP32[532 >> 2] = i18; 6442 HEAP32[540 >> 2] = -1; 6443 HEAP32[544 >> 2] = -1; 6444 HEAP32[548 >> 2] = 0; 6445 HEAP32[500 >> 2] = 0; 6446 HEAP32[132] = (_time(0) | 0) & -16 ^ 1431655768; 6447 break; 6448 } else { 6449 _abort(); 6450 } 6451 } 6452 } while (0); 6453 i20 = i12 + 48 | 0; 6454 i25 = HEAP32[536 >> 2] | 0; 6455 i21 = i12 + 47 | 0; 6456 i22 = i25 + i21 | 0; 6457 i25 = 0 - i25 | 0; 6458 i18 = i22 & i25; 6459 if (!(i18 >>> 0 > i12 >>> 0)) { 6460 i32 = 0; 6461 STACKTOP = i1; 6462 return i32 | 0; 6463 } 6464 i24 = HEAP32[496 >> 2] | 0; 6465 if ((i24 | 0) != 0 ? (i31 = HEAP32[488 >> 2] | 0, i32 = i31 + i18 | 0, i32 >>> 0 <= i31 >>> 0 | i32 >>> 0 > i24 >>> 0) : 0) { 6466 i32 = 0; 6467 STACKTOP = i1; 6468 return i32 | 0; 6469 } 6470 L269 : do { 6471 if ((HEAP32[500 >> 2] & 4 | 0) == 0) { 6472 i26 = HEAP32[80 >> 2] | 0; 6473 L271 : do { 6474 if ((i26 | 0) != 0) { 6475 i24 = 504 | 0; 6476 while (1) { 6477 i27 = HEAP32[i24 >> 2] | 0; 6478 if (!(i27 >>> 0 > i26 >>> 0) ? (i23 = i24 + 4 | 0, (i27 + (HEAP32[i23 >> 2] | 0) | 0) >>> 0 > i26 >>> 0) : 0) { 6479 break; 6480 } 6481 i24 = HEAP32[i24 + 8 >> 2] | 0; 6482 if ((i24 | 0) == 0) { 6483 i13 = 182; 6484 break L271; 6485 } 6486 } 6487 if ((i24 | 0) != 0) { 6488 i25 = i22 - (HEAP32[68 >> 2] | 0) & i25; 6489 if (i25 >>> 0 < 2147483647) { 6490 i13 = _sbrk(i25 | 0) | 0; 6491 i26 = (i13 | 0) == ((HEAP32[i24 >> 2] | 0) + (HEAP32[i23 >> 2] | 0) | 0); 6492 i22 = i13; 6493 i24 = i25; 6494 i23 = i26 ? i13 : -1; 6495 i25 = i26 ? i25 : 0; 6496 i13 = 191; 6497 } else { 6498 i25 = 0; 6499 } 6500 } else { 6501 i13 = 182; 6502 } 6503 } else { 6504 i13 = 182; 6505 } 6506 } while (0); 6507 do { 6508 if ((i13 | 0) == 182) { 6509 i23 = _sbrk(0) | 0; 6510 if ((i23 | 0) != (-1 | 0)) { 6511 i24 = i23; 6512 i22 = HEAP32[532 >> 2] | 0; 6513 i25 = i22 + -1 | 0; 6514 if ((i25 & i24 | 0) == 0) { 6515 i25 = i18; 6516 } else { 6517 i25 = i18 - i24 + (i25 + i24 & 0 - i22) | 0; 6518 } 6519 i24 = HEAP32[488 >> 2] | 0; 6520 i26 = i24 + i25 | 0; 6521 if (i25 >>> 0 > i12 >>> 0 & i25 >>> 0 < 2147483647) { 6522 i22 = HEAP32[496 >> 2] | 0; 6523 if ((i22 | 0) != 0 ? i26 >>> 0 <= i24 >>> 0 | i26 >>> 0 > i22 >>> 0 : 0) { 6524 i25 = 0; 6525 break; 6526 } 6527 i22 = _sbrk(i25 | 0) | 0; 6528 i13 = (i22 | 0) == (i23 | 0); 6529 i24 = i25; 6530 i23 = i13 ? i23 : -1; 6531 i25 = i13 ? i25 : 0; 6532 i13 = 191; 6533 } else { 6534 i25 = 0; 6535 } 6536 } else { 6537 i25 = 0; 6538 } 6539 } 6540 } while (0); 6541 L291 : do { 6542 if ((i13 | 0) == 191) { 6543 i13 = 0 - i24 | 0; 6544 if ((i23 | 0) != (-1 | 0)) { 6545 i17 = i23; 6546 i14 = i25; 6547 i13 = 202; 6548 break L269; 6549 } 6550 do { 6551 if ((i22 | 0) != (-1 | 0) & i24 >>> 0 < 2147483647 & i24 >>> 0 < i20 >>> 0 ? (i19 = HEAP32[536 >> 2] | 0, i19 = i21 - i24 + i19 & 0 - i19, i19 >>> 0 < 2147483647) : 0) { 6552 if ((_sbrk(i19 | 0) | 0) == (-1 | 0)) { 6553 _sbrk(i13 | 0) | 0; 6554 break L291; 6555 } else { 6556 i24 = i19 + i24 | 0; 6557 break; 6558 } 6559 } 6560 } while (0); 6561 if ((i22 | 0) != (-1 | 0)) { 6562 i17 = i22; 6563 i14 = i24; 6564 i13 = 202; 6565 break L269; 6566 } 6567 } 6568 } while (0); 6569 HEAP32[500 >> 2] = HEAP32[500 >> 2] | 4; 6570 i13 = 199; 6571 } else { 6572 i25 = 0; 6573 i13 = 199; 6574 } 6575 } while (0); 6576 if ((((i13 | 0) == 199 ? i18 >>> 0 < 2147483647 : 0) ? (i17 = _sbrk(i18 | 0) | 0, i16 = _sbrk(0) | 0, (i16 | 0) != (-1 | 0) & (i17 | 0) != (-1 | 0) & i17 >>> 0 < i16 >>> 0) : 0) ? (i15 = i16 - i17 | 0, i14 = i15 >>> 0 > (i12 + 40 | 0) >>> 0, i14) : 0) { 6577 i14 = i14 ? i15 : i25; 6578 i13 = 202; 6579 } 6580 if ((i13 | 0) == 202) { 6581 i15 = (HEAP32[488 >> 2] | 0) + i14 | 0; 6582 HEAP32[488 >> 2] = i15; 6583 if (i15 >>> 0 > (HEAP32[492 >> 2] | 0) >>> 0) { 6584 HEAP32[492 >> 2] = i15; 6585 } 6586 i15 = HEAP32[80 >> 2] | 0; 6587 L311 : do { 6588 if ((i15 | 0) != 0) { 6589 i21 = 504 | 0; 6590 while (1) { 6591 i16 = HEAP32[i21 >> 2] | 0; 6592 i19 = i21 + 4 | 0; 6593 i20 = HEAP32[i19 >> 2] | 0; 6594 if ((i17 | 0) == (i16 + i20 | 0)) { 6595 i13 = 214; 6596 break; 6597 } 6598 i18 = HEAP32[i21 + 8 >> 2] | 0; 6599 if ((i18 | 0) == 0) { 6600 break; 6601 } else { 6602 i21 = i18; 6603 } 6604 } 6605 if (((i13 | 0) == 214 ? (HEAP32[i21 + 12 >> 2] & 8 | 0) == 0 : 0) ? i15 >>> 0 >= i16 >>> 0 & i15 >>> 0 < i17 >>> 0 : 0) { 6606 HEAP32[i19 >> 2] = i20 + i14; 6607 i2 = (HEAP32[68 >> 2] | 0) + i14 | 0; 6608 i3 = i15 + 8 | 0; 6609 if ((i3 & 7 | 0) == 0) { 6610 i3 = 0; 6611 } else { 6612 i3 = 0 - i3 & 7; 6613 } 6614 i32 = i2 - i3 | 0; 6615 HEAP32[80 >> 2] = i15 + i3; 6616 HEAP32[68 >> 2] = i32; 6617 HEAP32[i15 + (i3 + 4) >> 2] = i32 | 1; 6618 HEAP32[i15 + (i2 + 4) >> 2] = 40; 6619 HEAP32[84 >> 2] = HEAP32[544 >> 2]; 6620 break; 6621 } 6622 if (i17 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6623 HEAP32[72 >> 2] = i17; 6624 } 6625 i19 = i17 + i14 | 0; 6626 i16 = 504 | 0; 6627 while (1) { 6628 if ((HEAP32[i16 >> 2] | 0) == (i19 | 0)) { 6629 i13 = 224; 6630 break; 6631 } 6632 i18 = HEAP32[i16 + 8 >> 2] | 0; 6633 if ((i18 | 0) == 0) { 6634 break; 6635 } else { 6636 i16 = i18; 6637 } 6638 } 6639 if ((i13 | 0) == 224 ? (HEAP32[i16 + 12 >> 2] & 8 | 0) == 0 : 0) { 6640 HEAP32[i16 >> 2] = i17; 6641 i6 = i16 + 4 | 0; 6642 HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + i14; 6643 i6 = i17 + 8 | 0; 6644 if ((i6 & 7 | 0) == 0) { 6645 i6 = 0; 6646 } else { 6647 i6 = 0 - i6 & 7; 6648 } 6649 i7 = i17 + (i14 + 8) | 0; 6650 if ((i7 & 7 | 0) == 0) { 6651 i13 = 0; 6652 } else { 6653 i13 = 0 - i7 & 7; 6654 } 6655 i15 = i17 + (i13 + i14) | 0; 6656 i8 = i6 + i12 | 0; 6657 i7 = i17 + i8 | 0; 6658 i10 = i15 - (i17 + i6) - i12 | 0; 6659 HEAP32[i17 + (i6 + 4) >> 2] = i12 | 3; 6660 L348 : do { 6661 if ((i15 | 0) != (HEAP32[80 >> 2] | 0)) { 6662 if ((i15 | 0) == (HEAP32[76 >> 2] | 0)) { 6663 i32 = (HEAP32[64 >> 2] | 0) + i10 | 0; 6664 HEAP32[64 >> 2] = i32; 6665 HEAP32[76 >> 2] = i7; 6666 HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1; 6667 HEAP32[i17 + (i32 + i8) >> 2] = i32; 6668 break; 6669 } 6670 i12 = i14 + 4 | 0; 6671 i18 = HEAP32[i17 + (i12 + i13) >> 2] | 0; 6672 if ((i18 & 3 | 0) == 1) { 6673 i11 = i18 & -8; 6674 i16 = i18 >>> 3; 6675 do { 6676 if (!(i18 >>> 0 < 256)) { 6677 i9 = HEAP32[i17 + ((i13 | 24) + i14) >> 2] | 0; 6678 i19 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0; 6679 do { 6680 if ((i19 | 0) == (i15 | 0)) { 6681 i19 = i13 | 16; 6682 i18 = i17 + (i12 + i19) | 0; 6683 i16 = HEAP32[i18 >> 2] | 0; 6684 if ((i16 | 0) == 0) { 6685 i18 = i17 + (i19 + i14) | 0; 6686 i16 = HEAP32[i18 >> 2] | 0; 6687 if ((i16 | 0) == 0) { 6688 i5 = 0; 6689 break; 6690 } 6691 } 6692 while (1) { 6693 i20 = i16 + 20 | 0; 6694 i19 = HEAP32[i20 >> 2] | 0; 6695 if ((i19 | 0) != 0) { 6696 i16 = i19; 6697 i18 = i20; 6698 continue; 6699 } 6700 i19 = i16 + 16 | 0; 6701 i20 = HEAP32[i19 >> 2] | 0; 6702 if ((i20 | 0) == 0) { 6703 break; 6704 } else { 6705 i16 = i20; 6706 i18 = i19; 6707 } 6708 } 6709 if (i18 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6710 _abort(); 6711 } else { 6712 HEAP32[i18 >> 2] = 0; 6713 i5 = i16; 6714 break; 6715 } 6716 } else { 6717 i18 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0; 6718 if (i18 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6719 _abort(); 6720 } 6721 i16 = i18 + 12 | 0; 6722 if ((HEAP32[i16 >> 2] | 0) != (i15 | 0)) { 6723 _abort(); 6724 } 6725 i20 = i19 + 8 | 0; 6726 if ((HEAP32[i20 >> 2] | 0) == (i15 | 0)) { 6727 HEAP32[i16 >> 2] = i19; 6728 HEAP32[i20 >> 2] = i18; 6729 i5 = i19; 6730 break; 6731 } else { 6732 _abort(); 6733 } 6734 } 6735 } while (0); 6736 if ((i9 | 0) != 0) { 6737 i16 = HEAP32[i17 + (i14 + 28 + i13) >> 2] | 0; 6738 i18 = 360 + (i16 << 2) | 0; 6739 if ((i15 | 0) == (HEAP32[i18 >> 2] | 0)) { 6740 HEAP32[i18 >> 2] = i5; 6741 if ((i5 | 0) == 0) { 6742 HEAP32[60 >> 2] = HEAP32[60 >> 2] & ~(1 << i16); 6743 break; 6744 } 6745 } else { 6746 if (i9 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6747 _abort(); 6748 } 6749 i16 = i9 + 16 | 0; 6750 if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) { 6751 HEAP32[i16 >> 2] = i5; 6752 } else { 6753 HEAP32[i9 + 20 >> 2] = i5; 6754 } 6755 if ((i5 | 0) == 0) { 6756 break; 6757 } 6758 } 6759 if (i5 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6760 _abort(); 6761 } 6762 HEAP32[i5 + 24 >> 2] = i9; 6763 i15 = i13 | 16; 6764 i9 = HEAP32[i17 + (i15 + i14) >> 2] | 0; 6765 do { 6766 if ((i9 | 0) != 0) { 6767 if (i9 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6768 _abort(); 6769 } else { 6770 HEAP32[i5 + 16 >> 2] = i9; 6771 HEAP32[i9 + 24 >> 2] = i5; 6772 break; 6773 } 6774 } 6775 } while (0); 6776 i9 = HEAP32[i17 + (i12 + i15) >> 2] | 0; 6777 if ((i9 | 0) != 0) { 6778 if (i9 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6779 _abort(); 6780 } else { 6781 HEAP32[i5 + 20 >> 2] = i9; 6782 HEAP32[i9 + 24 >> 2] = i5; 6783 break; 6784 } 6785 } 6786 } 6787 } else { 6788 i5 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0; 6789 i12 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0; 6790 i18 = 96 + (i16 << 1 << 2) | 0; 6791 if ((i5 | 0) != (i18 | 0)) { 6792 if (i5 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6793 _abort(); 6794 } 6795 if ((HEAP32[i5 + 12 >> 2] | 0) != (i15 | 0)) { 6796 _abort(); 6797 } 6798 } 6799 if ((i12 | 0) == (i5 | 0)) { 6800 HEAP32[14] = HEAP32[14] & ~(1 << i16); 6801 break; 6802 } 6803 if ((i12 | 0) != (i18 | 0)) { 6804 if (i12 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6805 _abort(); 6806 } 6807 i16 = i12 + 8 | 0; 6808 if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) { 6809 i9 = i16; 6810 } else { 6811 _abort(); 6812 } 6813 } else { 6814 i9 = i12 + 8 | 0; 6815 } 6816 HEAP32[i5 + 12 >> 2] = i12; 6817 HEAP32[i9 >> 2] = i5; 6818 } 6819 } while (0); 6820 i15 = i17 + ((i11 | i13) + i14) | 0; 6821 i10 = i11 + i10 | 0; 6822 } 6823 i5 = i15 + 4 | 0; 6824 HEAP32[i5 >> 2] = HEAP32[i5 >> 2] & -2; 6825 HEAP32[i17 + (i8 + 4) >> 2] = i10 | 1; 6826 HEAP32[i17 + (i10 + i8) >> 2] = i10; 6827 i5 = i10 >>> 3; 6828 if (i10 >>> 0 < 256) { 6829 i10 = i5 << 1; 6830 i2 = 96 + (i10 << 2) | 0; 6831 i9 = HEAP32[14] | 0; 6832 i5 = 1 << i5; 6833 if ((i9 & i5 | 0) != 0) { 6834 i9 = 96 + (i10 + 2 << 2) | 0; 6835 i5 = HEAP32[i9 >> 2] | 0; 6836 if (i5 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6837 _abort(); 6838 } else { 6839 i3 = i9; 6840 i4 = i5; 6841 } 6842 } else { 6843 HEAP32[14] = i9 | i5; 6844 i3 = 96 + (i10 + 2 << 2) | 0; 6845 i4 = i2; 6846 } 6847 HEAP32[i3 >> 2] = i7; 6848 HEAP32[i4 + 12 >> 2] = i7; 6849 HEAP32[i17 + (i8 + 8) >> 2] = i4; 6850 HEAP32[i17 + (i8 + 12) >> 2] = i2; 6851 break; 6852 } 6853 i3 = i10 >>> 8; 6854 if ((i3 | 0) != 0) { 6855 if (i10 >>> 0 > 16777215) { 6856 i3 = 31; 6857 } else { 6858 i31 = (i3 + 1048320 | 0) >>> 16 & 8; 6859 i32 = i3 << i31; 6860 i30 = (i32 + 520192 | 0) >>> 16 & 4; 6861 i32 = i32 << i30; 6862 i3 = (i32 + 245760 | 0) >>> 16 & 2; 6863 i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0; 6864 i3 = i10 >>> (i3 + 7 | 0) & 1 | i3 << 1; 6865 } 6866 } else { 6867 i3 = 0; 6868 } 6869 i4 = 360 + (i3 << 2) | 0; 6870 HEAP32[i17 + (i8 + 28) >> 2] = i3; 6871 HEAP32[i17 + (i8 + 20) >> 2] = 0; 6872 HEAP32[i17 + (i8 + 16) >> 2] = 0; 6873 i9 = HEAP32[60 >> 2] | 0; 6874 i5 = 1 << i3; 6875 if ((i9 & i5 | 0) == 0) { 6876 HEAP32[60 >> 2] = i9 | i5; 6877 HEAP32[i4 >> 2] = i7; 6878 HEAP32[i17 + (i8 + 24) >> 2] = i4; 6879 HEAP32[i17 + (i8 + 12) >> 2] = i7; 6880 HEAP32[i17 + (i8 + 8) >> 2] = i7; 6881 break; 6882 } 6883 i4 = HEAP32[i4 >> 2] | 0; 6884 if ((i3 | 0) == 31) { 6885 i3 = 0; 6886 } else { 6887 i3 = 25 - (i3 >>> 1) | 0; 6888 } 6889 L444 : do { 6890 if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i10 | 0)) { 6891 i3 = i10 << i3; 6892 while (1) { 6893 i5 = i4 + (i3 >>> 31 << 2) + 16 | 0; 6894 i9 = HEAP32[i5 >> 2] | 0; 6895 if ((i9 | 0) == 0) { 6896 break; 6897 } 6898 if ((HEAP32[i9 + 4 >> 2] & -8 | 0) == (i10 | 0)) { 6899 i2 = i9; 6900 break L444; 6901 } else { 6902 i3 = i3 << 1; 6903 i4 = i9; 6904 } 6905 } 6906 if (i5 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 6907 _abort(); 6908 } else { 6909 HEAP32[i5 >> 2] = i7; 6910 HEAP32[i17 + (i8 + 24) >> 2] = i4; 6911 HEAP32[i17 + (i8 + 12) >> 2] = i7; 6912 HEAP32[i17 + (i8 + 8) >> 2] = i7; 6913 break L348; 6914 } 6915 } else { 6916 i2 = i4; 6917 } 6918 } while (0); 6919 i4 = i2 + 8 | 0; 6920 i3 = HEAP32[i4 >> 2] | 0; 6921 i5 = HEAP32[72 >> 2] | 0; 6922 if (i2 >>> 0 < i5 >>> 0) { 6923 _abort(); 6924 } 6925 if (i3 >>> 0 < i5 >>> 0) { 6926 _abort(); 6927 } else { 6928 HEAP32[i3 + 12 >> 2] = i7; 6929 HEAP32[i4 >> 2] = i7; 6930 HEAP32[i17 + (i8 + 8) >> 2] = i3; 6931 HEAP32[i17 + (i8 + 12) >> 2] = i2; 6932 HEAP32[i17 + (i8 + 24) >> 2] = 0; 6933 break; 6934 } 6935 } else { 6936 i32 = (HEAP32[68 >> 2] | 0) + i10 | 0; 6937 HEAP32[68 >> 2] = i32; 6938 HEAP32[80 >> 2] = i7; 6939 HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1; 6940 } 6941 } while (0); 6942 i32 = i17 + (i6 | 8) | 0; 6943 STACKTOP = i1; 6944 return i32 | 0; 6945 } 6946 i3 = 504 | 0; 6947 while (1) { 6948 i2 = HEAP32[i3 >> 2] | 0; 6949 if (!(i2 >>> 0 > i15 >>> 0) ? (i11 = HEAP32[i3 + 4 >> 2] | 0, i10 = i2 + i11 | 0, i10 >>> 0 > i15 >>> 0) : 0) { 6950 break; 6951 } 6952 i3 = HEAP32[i3 + 8 >> 2] | 0; 6953 } 6954 i3 = i2 + (i11 + -39) | 0; 6955 if ((i3 & 7 | 0) == 0) { 6956 i3 = 0; 6957 } else { 6958 i3 = 0 - i3 & 7; 6959 } 6960 i2 = i2 + (i11 + -47 + i3) | 0; 6961 i2 = i2 >>> 0 < (i15 + 16 | 0) >>> 0 ? i15 : i2; 6962 i3 = i2 + 8 | 0; 6963 i4 = i17 + 8 | 0; 6964 if ((i4 & 7 | 0) == 0) { 6965 i4 = 0; 6966 } else { 6967 i4 = 0 - i4 & 7; 6968 } 6969 i32 = i14 + -40 - i4 | 0; 6970 HEAP32[80 >> 2] = i17 + i4; 6971 HEAP32[68 >> 2] = i32; 6972 HEAP32[i17 + (i4 + 4) >> 2] = i32 | 1; 6973 HEAP32[i17 + (i14 + -36) >> 2] = 40; 6974 HEAP32[84 >> 2] = HEAP32[544 >> 2]; 6975 HEAP32[i2 + 4 >> 2] = 27; 6976 HEAP32[i3 + 0 >> 2] = HEAP32[504 >> 2]; 6977 HEAP32[i3 + 4 >> 2] = HEAP32[508 >> 2]; 6978 HEAP32[i3 + 8 >> 2] = HEAP32[512 >> 2]; 6979 HEAP32[i3 + 12 >> 2] = HEAP32[516 >> 2]; 6980 HEAP32[504 >> 2] = i17; 6981 HEAP32[508 >> 2] = i14; 6982 HEAP32[516 >> 2] = 0; 6983 HEAP32[512 >> 2] = i3; 6984 i4 = i2 + 28 | 0; 6985 HEAP32[i4 >> 2] = 7; 6986 if ((i2 + 32 | 0) >>> 0 < i10 >>> 0) { 6987 while (1) { 6988 i3 = i4 + 4 | 0; 6989 HEAP32[i3 >> 2] = 7; 6990 if ((i4 + 8 | 0) >>> 0 < i10 >>> 0) { 6991 i4 = i3; 6992 } else { 6993 break; 6994 } 6995 } 6996 } 6997 if ((i2 | 0) != (i15 | 0)) { 6998 i2 = i2 - i15 | 0; 6999 i3 = i15 + (i2 + 4) | 0; 7000 HEAP32[i3 >> 2] = HEAP32[i3 >> 2] & -2; 7001 HEAP32[i15 + 4 >> 2] = i2 | 1; 7002 HEAP32[i15 + i2 >> 2] = i2; 7003 i3 = i2 >>> 3; 7004 if (i2 >>> 0 < 256) { 7005 i4 = i3 << 1; 7006 i2 = 96 + (i4 << 2) | 0; 7007 i5 = HEAP32[14] | 0; 7008 i3 = 1 << i3; 7009 if ((i5 & i3 | 0) != 0) { 7010 i4 = 96 + (i4 + 2 << 2) | 0; 7011 i3 = HEAP32[i4 >> 2] | 0; 7012 if (i3 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 7013 _abort(); 7014 } else { 7015 i7 = i4; 7016 i8 = i3; 7017 } 7018 } else { 7019 HEAP32[14] = i5 | i3; 7020 i7 = 96 + (i4 + 2 << 2) | 0; 7021 i8 = i2; 7022 } 7023 HEAP32[i7 >> 2] = i15; 7024 HEAP32[i8 + 12 >> 2] = i15; 7025 HEAP32[i15 + 8 >> 2] = i8; 7026 HEAP32[i15 + 12 >> 2] = i2; 7027 break; 7028 } 7029 i3 = i2 >>> 8; 7030 if ((i3 | 0) != 0) { 7031 if (i2 >>> 0 > 16777215) { 7032 i3 = 31; 7033 } else { 7034 i31 = (i3 + 1048320 | 0) >>> 16 & 8; 7035 i32 = i3 << i31; 7036 i30 = (i32 + 520192 | 0) >>> 16 & 4; 7037 i32 = i32 << i30; 7038 i3 = (i32 + 245760 | 0) >>> 16 & 2; 7039 i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0; 7040 i3 = i2 >>> (i3 + 7 | 0) & 1 | i3 << 1; 7041 } 7042 } else { 7043 i3 = 0; 7044 } 7045 i7 = 360 + (i3 << 2) | 0; 7046 HEAP32[i15 + 28 >> 2] = i3; 7047 HEAP32[i15 + 20 >> 2] = 0; 7048 HEAP32[i15 + 16 >> 2] = 0; 7049 i4 = HEAP32[60 >> 2] | 0; 7050 i5 = 1 << i3; 7051 if ((i4 & i5 | 0) == 0) { 7052 HEAP32[60 >> 2] = i4 | i5; 7053 HEAP32[i7 >> 2] = i15; 7054 HEAP32[i15 + 24 >> 2] = i7; 7055 HEAP32[i15 + 12 >> 2] = i15; 7056 HEAP32[i15 + 8 >> 2] = i15; 7057 break; 7058 } 7059 i4 = HEAP32[i7 >> 2] | 0; 7060 if ((i3 | 0) == 31) { 7061 i3 = 0; 7062 } else { 7063 i3 = 25 - (i3 >>> 1) | 0; 7064 } 7065 L499 : do { 7066 if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i2 | 0)) { 7067 i3 = i2 << i3; 7068 while (1) { 7069 i7 = i4 + (i3 >>> 31 << 2) + 16 | 0; 7070 i5 = HEAP32[i7 >> 2] | 0; 7071 if ((i5 | 0) == 0) { 7072 break; 7073 } 7074 if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i2 | 0)) { 7075 i6 = i5; 7076 break L499; 7077 } else { 7078 i3 = i3 << 1; 7079 i4 = i5; 7080 } 7081 } 7082 if (i7 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 7083 _abort(); 7084 } else { 7085 HEAP32[i7 >> 2] = i15; 7086 HEAP32[i15 + 24 >> 2] = i4; 7087 HEAP32[i15 + 12 >> 2] = i15; 7088 HEAP32[i15 + 8 >> 2] = i15; 7089 break L311; 7090 } 7091 } else { 7092 i6 = i4; 7093 } 7094 } while (0); 7095 i4 = i6 + 8 | 0; 7096 i3 = HEAP32[i4 >> 2] | 0; 7097 i2 = HEAP32[72 >> 2] | 0; 7098 if (i6 >>> 0 < i2 >>> 0) { 7099 _abort(); 7100 } 7101 if (i3 >>> 0 < i2 >>> 0) { 7102 _abort(); 7103 } else { 7104 HEAP32[i3 + 12 >> 2] = i15; 7105 HEAP32[i4 >> 2] = i15; 7106 HEAP32[i15 + 8 >> 2] = i3; 7107 HEAP32[i15 + 12 >> 2] = i6; 7108 HEAP32[i15 + 24 >> 2] = 0; 7109 break; 7110 } 7111 } 7112 } else { 7113 i32 = HEAP32[72 >> 2] | 0; 7114 if ((i32 | 0) == 0 | i17 >>> 0 < i32 >>> 0) { 7115 HEAP32[72 >> 2] = i17; 7116 } 7117 HEAP32[504 >> 2] = i17; 7118 HEAP32[508 >> 2] = i14; 7119 HEAP32[516 >> 2] = 0; 7120 HEAP32[92 >> 2] = HEAP32[132]; 7121 HEAP32[88 >> 2] = -1; 7122 i2 = 0; 7123 do { 7124 i32 = i2 << 1; 7125 i31 = 96 + (i32 << 2) | 0; 7126 HEAP32[96 + (i32 + 3 << 2) >> 2] = i31; 7127 HEAP32[96 + (i32 + 2 << 2) >> 2] = i31; 7128 i2 = i2 + 1 | 0; 7129 } while ((i2 | 0) != 32); 7130 i2 = i17 + 8 | 0; 7131 if ((i2 & 7 | 0) == 0) { 7132 i2 = 0; 7133 } else { 7134 i2 = 0 - i2 & 7; 7135 } 7136 i32 = i14 + -40 - i2 | 0; 7137 HEAP32[80 >> 2] = i17 + i2; 7138 HEAP32[68 >> 2] = i32; 7139 HEAP32[i17 + (i2 + 4) >> 2] = i32 | 1; 7140 HEAP32[i17 + (i14 + -36) >> 2] = 40; 7141 HEAP32[84 >> 2] = HEAP32[544 >> 2]; 7142 } 7143 } while (0); 7144 i2 = HEAP32[68 >> 2] | 0; 7145 if (i2 >>> 0 > i12 >>> 0) { 7146 i31 = i2 - i12 | 0; 7147 HEAP32[68 >> 2] = i31; 7148 i32 = HEAP32[80 >> 2] | 0; 7149 HEAP32[80 >> 2] = i32 + i12; 7150 HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1; 7151 HEAP32[i32 + 4 >> 2] = i12 | 3; 7152 i32 = i32 + 8 | 0; 7153 STACKTOP = i1; 7154 return i32 | 0; 7155 } 7156 } 7157 HEAP32[(___errno_location() | 0) >> 2] = 12; 7158 i32 = 0; 7159 STACKTOP = i1; 7160 return i32 | 0; 7161} 7162function _free(i7) { 7163 i7 = i7 | 0; 7164 var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0; 7165 i1 = STACKTOP; 7166 if ((i7 | 0) == 0) { 7167 STACKTOP = i1; 7168 return; 7169 } 7170 i15 = i7 + -8 | 0; 7171 i16 = HEAP32[72 >> 2] | 0; 7172 if (i15 >>> 0 < i16 >>> 0) { 7173 _abort(); 7174 } 7175 i13 = HEAP32[i7 + -4 >> 2] | 0; 7176 i12 = i13 & 3; 7177 if ((i12 | 0) == 1) { 7178 _abort(); 7179 } 7180 i8 = i13 & -8; 7181 i6 = i7 + (i8 + -8) | 0; 7182 do { 7183 if ((i13 & 1 | 0) == 0) { 7184 i19 = HEAP32[i15 >> 2] | 0; 7185 if ((i12 | 0) == 0) { 7186 STACKTOP = i1; 7187 return; 7188 } 7189 i15 = -8 - i19 | 0; 7190 i13 = i7 + i15 | 0; 7191 i12 = i19 + i8 | 0; 7192 if (i13 >>> 0 < i16 >>> 0) { 7193 _abort(); 7194 } 7195 if ((i13 | 0) == (HEAP32[76 >> 2] | 0)) { 7196 i2 = i7 + (i8 + -4) | 0; 7197 if ((HEAP32[i2 >> 2] & 3 | 0) != 3) { 7198 i2 = i13; 7199 i11 = i12; 7200 break; 7201 } 7202 HEAP32[64 >> 2] = i12; 7203 HEAP32[i2 >> 2] = HEAP32[i2 >> 2] & -2; 7204 HEAP32[i7 + (i15 + 4) >> 2] = i12 | 1; 7205 HEAP32[i6 >> 2] = i12; 7206 STACKTOP = i1; 7207 return; 7208 } 7209 i18 = i19 >>> 3; 7210 if (i19 >>> 0 < 256) { 7211 i2 = HEAP32[i7 + (i15 + 8) >> 2] | 0; 7212 i11 = HEAP32[i7 + (i15 + 12) >> 2] | 0; 7213 i14 = 96 + (i18 << 1 << 2) | 0; 7214 if ((i2 | 0) != (i14 | 0)) { 7215 if (i2 >>> 0 < i16 >>> 0) { 7216 _abort(); 7217 } 7218 if ((HEAP32[i2 + 12 >> 2] | 0) != (i13 | 0)) { 7219 _abort(); 7220 } 7221 } 7222 if ((i11 | 0) == (i2 | 0)) { 7223 HEAP32[14] = HEAP32[14] & ~(1 << i18); 7224 i2 = i13; 7225 i11 = i12; 7226 break; 7227 } 7228 if ((i11 | 0) != (i14 | 0)) { 7229 if (i11 >>> 0 < i16 >>> 0) { 7230 _abort(); 7231 } 7232 i14 = i11 + 8 | 0; 7233 if ((HEAP32[i14 >> 2] | 0) == (i13 | 0)) { 7234 i17 = i14; 7235 } else { 7236 _abort(); 7237 } 7238 } else { 7239 i17 = i11 + 8 | 0; 7240 } 7241 HEAP32[i2 + 12 >> 2] = i11; 7242 HEAP32[i17 >> 2] = i2; 7243 i2 = i13; 7244 i11 = i12; 7245 break; 7246 } 7247 i17 = HEAP32[i7 + (i15 + 24) >> 2] | 0; 7248 i18 = HEAP32[i7 + (i15 + 12) >> 2] | 0; 7249 do { 7250 if ((i18 | 0) == (i13 | 0)) { 7251 i19 = i7 + (i15 + 20) | 0; 7252 i18 = HEAP32[i19 >> 2] | 0; 7253 if ((i18 | 0) == 0) { 7254 i19 = i7 + (i15 + 16) | 0; 7255 i18 = HEAP32[i19 >> 2] | 0; 7256 if ((i18 | 0) == 0) { 7257 i14 = 0; 7258 break; 7259 } 7260 } 7261 while (1) { 7262 i21 = i18 + 20 | 0; 7263 i20 = HEAP32[i21 >> 2] | 0; 7264 if ((i20 | 0) != 0) { 7265 i18 = i20; 7266 i19 = i21; 7267 continue; 7268 } 7269 i20 = i18 + 16 | 0; 7270 i21 = HEAP32[i20 >> 2] | 0; 7271 if ((i21 | 0) == 0) { 7272 break; 7273 } else { 7274 i18 = i21; 7275 i19 = i20; 7276 } 7277 } 7278 if (i19 >>> 0 < i16 >>> 0) { 7279 _abort(); 7280 } else { 7281 HEAP32[i19 >> 2] = 0; 7282 i14 = i18; 7283 break; 7284 } 7285 } else { 7286 i19 = HEAP32[i7 + (i15 + 8) >> 2] | 0; 7287 if (i19 >>> 0 < i16 >>> 0) { 7288 _abort(); 7289 } 7290 i16 = i19 + 12 | 0; 7291 if ((HEAP32[i16 >> 2] | 0) != (i13 | 0)) { 7292 _abort(); 7293 } 7294 i20 = i18 + 8 | 0; 7295 if ((HEAP32[i20 >> 2] | 0) == (i13 | 0)) { 7296 HEAP32[i16 >> 2] = i18; 7297 HEAP32[i20 >> 2] = i19; 7298 i14 = i18; 7299 break; 7300 } else { 7301 _abort(); 7302 } 7303 } 7304 } while (0); 7305 if ((i17 | 0) != 0) { 7306 i18 = HEAP32[i7 + (i15 + 28) >> 2] | 0; 7307 i16 = 360 + (i18 << 2) | 0; 7308 if ((i13 | 0) == (HEAP32[i16 >> 2] | 0)) { 7309 HEAP32[i16 >> 2] = i14; 7310 if ((i14 | 0) == 0) { 7311 HEAP32[60 >> 2] = HEAP32[60 >> 2] & ~(1 << i18); 7312 i2 = i13; 7313 i11 = i12; 7314 break; 7315 } 7316 } else { 7317 if (i17 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 7318 _abort(); 7319 } 7320 i16 = i17 + 16 | 0; 7321 if ((HEAP32[i16 >> 2] | 0) == (i13 | 0)) { 7322 HEAP32[i16 >> 2] = i14; 7323 } else { 7324 HEAP32[i17 + 20 >> 2] = i14; 7325 } 7326 if ((i14 | 0) == 0) { 7327 i2 = i13; 7328 i11 = i12; 7329 break; 7330 } 7331 } 7332 if (i14 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 7333 _abort(); 7334 } 7335 HEAP32[i14 + 24 >> 2] = i17; 7336 i16 = HEAP32[i7 + (i15 + 16) >> 2] | 0; 7337 do { 7338 if ((i16 | 0) != 0) { 7339 if (i16 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 7340 _abort(); 7341 } else { 7342 HEAP32[i14 + 16 >> 2] = i16; 7343 HEAP32[i16 + 24 >> 2] = i14; 7344 break; 7345 } 7346 } 7347 } while (0); 7348 i15 = HEAP32[i7 + (i15 + 20) >> 2] | 0; 7349 if ((i15 | 0) != 0) { 7350 if (i15 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 7351 _abort(); 7352 } else { 7353 HEAP32[i14 + 20 >> 2] = i15; 7354 HEAP32[i15 + 24 >> 2] = i14; 7355 i2 = i13; 7356 i11 = i12; 7357 break; 7358 } 7359 } else { 7360 i2 = i13; 7361 i11 = i12; 7362 } 7363 } else { 7364 i2 = i13; 7365 i11 = i12; 7366 } 7367 } else { 7368 i2 = i15; 7369 i11 = i8; 7370 } 7371 } while (0); 7372 if (!(i2 >>> 0 < i6 >>> 0)) { 7373 _abort(); 7374 } 7375 i12 = i7 + (i8 + -4) | 0; 7376 i13 = HEAP32[i12 >> 2] | 0; 7377 if ((i13 & 1 | 0) == 0) { 7378 _abort(); 7379 } 7380 if ((i13 & 2 | 0) == 0) { 7381 if ((i6 | 0) == (HEAP32[80 >> 2] | 0)) { 7382 i21 = (HEAP32[68 >> 2] | 0) + i11 | 0; 7383 HEAP32[68 >> 2] = i21; 7384 HEAP32[80 >> 2] = i2; 7385 HEAP32[i2 + 4 >> 2] = i21 | 1; 7386 if ((i2 | 0) != (HEAP32[76 >> 2] | 0)) { 7387 STACKTOP = i1; 7388 return; 7389 } 7390 HEAP32[76 >> 2] = 0; 7391 HEAP32[64 >> 2] = 0; 7392 STACKTOP = i1; 7393 return; 7394 } 7395 if ((i6 | 0) == (HEAP32[76 >> 2] | 0)) { 7396 i21 = (HEAP32[64 >> 2] | 0) + i11 | 0; 7397 HEAP32[64 >> 2] = i21; 7398 HEAP32[76 >> 2] = i2; 7399 HEAP32[i2 + 4 >> 2] = i21 | 1; 7400 HEAP32[i2 + i21 >> 2] = i21; 7401 STACKTOP = i1; 7402 return; 7403 } 7404 i11 = (i13 & -8) + i11 | 0; 7405 i12 = i13 >>> 3; 7406 do { 7407 if (!(i13 >>> 0 < 256)) { 7408 i10 = HEAP32[i7 + (i8 + 16) >> 2] | 0; 7409 i15 = HEAP32[i7 + (i8 | 4) >> 2] | 0; 7410 do { 7411 if ((i15 | 0) == (i6 | 0)) { 7412 i13 = i7 + (i8 + 12) | 0; 7413 i12 = HEAP32[i13 >> 2] | 0; 7414 if ((i12 | 0) == 0) { 7415 i13 = i7 + (i8 + 8) | 0; 7416 i12 = HEAP32[i13 >> 2] | 0; 7417 if ((i12 | 0) == 0) { 7418 i9 = 0; 7419 break; 7420 } 7421 } 7422 while (1) { 7423 i14 = i12 + 20 | 0; 7424 i15 = HEAP32[i14 >> 2] | 0; 7425 if ((i15 | 0) != 0) { 7426 i12 = i15; 7427 i13 = i14; 7428 continue; 7429 } 7430 i14 = i12 + 16 | 0; 7431 i15 = HEAP32[i14 >> 2] | 0; 7432 if ((i15 | 0) == 0) { 7433 break; 7434 } else { 7435 i12 = i15; 7436 i13 = i14; 7437 } 7438 } 7439 if (i13 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 7440 _abort(); 7441 } else { 7442 HEAP32[i13 >> 2] = 0; 7443 i9 = i12; 7444 break; 7445 } 7446 } else { 7447 i13 = HEAP32[i7 + i8 >> 2] | 0; 7448 if (i13 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 7449 _abort(); 7450 } 7451 i14 = i13 + 12 | 0; 7452 if ((HEAP32[i14 >> 2] | 0) != (i6 | 0)) { 7453 _abort(); 7454 } 7455 i12 = i15 + 8 | 0; 7456 if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) { 7457 HEAP32[i14 >> 2] = i15; 7458 HEAP32[i12 >> 2] = i13; 7459 i9 = i15; 7460 break; 7461 } else { 7462 _abort(); 7463 } 7464 } 7465 } while (0); 7466 if ((i10 | 0) != 0) { 7467 i12 = HEAP32[i7 + (i8 + 20) >> 2] | 0; 7468 i13 = 360 + (i12 << 2) | 0; 7469 if ((i6 | 0) == (HEAP32[i13 >> 2] | 0)) { 7470 HEAP32[i13 >> 2] = i9; 7471 if ((i9 | 0) == 0) { 7472 HEAP32[60 >> 2] = HEAP32[60 >> 2] & ~(1 << i12); 7473 break; 7474 } 7475 } else { 7476 if (i10 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 7477 _abort(); 7478 } 7479 i12 = i10 + 16 | 0; 7480 if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) { 7481 HEAP32[i12 >> 2] = i9; 7482 } else { 7483 HEAP32[i10 + 20 >> 2] = i9; 7484 } 7485 if ((i9 | 0) == 0) { 7486 break; 7487 } 7488 } 7489 if (i9 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 7490 _abort(); 7491 } 7492 HEAP32[i9 + 24 >> 2] = i10; 7493 i6 = HEAP32[i7 + (i8 + 8) >> 2] | 0; 7494 do { 7495 if ((i6 | 0) != 0) { 7496 if (i6 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 7497 _abort(); 7498 } else { 7499 HEAP32[i9 + 16 >> 2] = i6; 7500 HEAP32[i6 + 24 >> 2] = i9; 7501 break; 7502 } 7503 } 7504 } while (0); 7505 i6 = HEAP32[i7 + (i8 + 12) >> 2] | 0; 7506 if ((i6 | 0) != 0) { 7507 if (i6 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 7508 _abort(); 7509 } else { 7510 HEAP32[i9 + 20 >> 2] = i6; 7511 HEAP32[i6 + 24 >> 2] = i9; 7512 break; 7513 } 7514 } 7515 } 7516 } else { 7517 i9 = HEAP32[i7 + i8 >> 2] | 0; 7518 i7 = HEAP32[i7 + (i8 | 4) >> 2] | 0; 7519 i8 = 96 + (i12 << 1 << 2) | 0; 7520 if ((i9 | 0) != (i8 | 0)) { 7521 if (i9 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 7522 _abort(); 7523 } 7524 if ((HEAP32[i9 + 12 >> 2] | 0) != (i6 | 0)) { 7525 _abort(); 7526 } 7527 } 7528 if ((i7 | 0) == (i9 | 0)) { 7529 HEAP32[14] = HEAP32[14] & ~(1 << i12); 7530 break; 7531 } 7532 if ((i7 | 0) != (i8 | 0)) { 7533 if (i7 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 7534 _abort(); 7535 } 7536 i8 = i7 + 8 | 0; 7537 if ((HEAP32[i8 >> 2] | 0) == (i6 | 0)) { 7538 i10 = i8; 7539 } else { 7540 _abort(); 7541 } 7542 } else { 7543 i10 = i7 + 8 | 0; 7544 } 7545 HEAP32[i9 + 12 >> 2] = i7; 7546 HEAP32[i10 >> 2] = i9; 7547 } 7548 } while (0); 7549 HEAP32[i2 + 4 >> 2] = i11 | 1; 7550 HEAP32[i2 + i11 >> 2] = i11; 7551 if ((i2 | 0) == (HEAP32[76 >> 2] | 0)) { 7552 HEAP32[64 >> 2] = i11; 7553 STACKTOP = i1; 7554 return; 7555 } 7556 } else { 7557 HEAP32[i12 >> 2] = i13 & -2; 7558 HEAP32[i2 + 4 >> 2] = i11 | 1; 7559 HEAP32[i2 + i11 >> 2] = i11; 7560 } 7561 i6 = i11 >>> 3; 7562 if (i11 >>> 0 < 256) { 7563 i7 = i6 << 1; 7564 i3 = 96 + (i7 << 2) | 0; 7565 i8 = HEAP32[14] | 0; 7566 i6 = 1 << i6; 7567 if ((i8 & i6 | 0) != 0) { 7568 i6 = 96 + (i7 + 2 << 2) | 0; 7569 i7 = HEAP32[i6 >> 2] | 0; 7570 if (i7 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 7571 _abort(); 7572 } else { 7573 i4 = i6; 7574 i5 = i7; 7575 } 7576 } else { 7577 HEAP32[14] = i8 | i6; 7578 i4 = 96 + (i7 + 2 << 2) | 0; 7579 i5 = i3; 7580 } 7581 HEAP32[i4 >> 2] = i2; 7582 HEAP32[i5 + 12 >> 2] = i2; 7583 HEAP32[i2 + 8 >> 2] = i5; 7584 HEAP32[i2 + 12 >> 2] = i3; 7585 STACKTOP = i1; 7586 return; 7587 } 7588 i4 = i11 >>> 8; 7589 if ((i4 | 0) != 0) { 7590 if (i11 >>> 0 > 16777215) { 7591 i4 = 31; 7592 } else { 7593 i20 = (i4 + 1048320 | 0) >>> 16 & 8; 7594 i21 = i4 << i20; 7595 i19 = (i21 + 520192 | 0) >>> 16 & 4; 7596 i21 = i21 << i19; 7597 i4 = (i21 + 245760 | 0) >>> 16 & 2; 7598 i4 = 14 - (i19 | i20 | i4) + (i21 << i4 >>> 15) | 0; 7599 i4 = i11 >>> (i4 + 7 | 0) & 1 | i4 << 1; 7600 } 7601 } else { 7602 i4 = 0; 7603 } 7604 i5 = 360 + (i4 << 2) | 0; 7605 HEAP32[i2 + 28 >> 2] = i4; 7606 HEAP32[i2 + 20 >> 2] = 0; 7607 HEAP32[i2 + 16 >> 2] = 0; 7608 i7 = HEAP32[60 >> 2] | 0; 7609 i6 = 1 << i4; 7610 L199 : do { 7611 if ((i7 & i6 | 0) != 0) { 7612 i5 = HEAP32[i5 >> 2] | 0; 7613 if ((i4 | 0) == 31) { 7614 i4 = 0; 7615 } else { 7616 i4 = 25 - (i4 >>> 1) | 0; 7617 } 7618 L205 : do { 7619 if ((HEAP32[i5 + 4 >> 2] & -8 | 0) != (i11 | 0)) { 7620 i4 = i11 << i4; 7621 i7 = i5; 7622 while (1) { 7623 i6 = i7 + (i4 >>> 31 << 2) + 16 | 0; 7624 i5 = HEAP32[i6 >> 2] | 0; 7625 if ((i5 | 0) == 0) { 7626 break; 7627 } 7628 if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i11 | 0)) { 7629 i3 = i5; 7630 break L205; 7631 } else { 7632 i4 = i4 << 1; 7633 i7 = i5; 7634 } 7635 } 7636 if (i6 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) { 7637 _abort(); 7638 } else { 7639 HEAP32[i6 >> 2] = i2; 7640 HEAP32[i2 + 24 >> 2] = i7; 7641 HEAP32[i2 + 12 >> 2] = i2; 7642 HEAP32[i2 + 8 >> 2] = i2; 7643 break L199; 7644 } 7645 } else { 7646 i3 = i5; 7647 } 7648 } while (0); 7649 i5 = i3 + 8 | 0; 7650 i4 = HEAP32[i5 >> 2] | 0; 7651 i6 = HEAP32[72 >> 2] | 0; 7652 if (i3 >>> 0 < i6 >>> 0) { 7653 _abort(); 7654 } 7655 if (i4 >>> 0 < i6 >>> 0) { 7656 _abort(); 7657 } else { 7658 HEAP32[i4 + 12 >> 2] = i2; 7659 HEAP32[i5 >> 2] = i2; 7660 HEAP32[i2 + 8 >> 2] = i4; 7661 HEAP32[i2 + 12 >> 2] = i3; 7662 HEAP32[i2 + 24 >> 2] = 0; 7663 break; 7664 } 7665 } else { 7666 HEAP32[60 >> 2] = i7 | i6; 7667 HEAP32[i5 >> 2] = i2; 7668 HEAP32[i2 + 24 >> 2] = i5; 7669 HEAP32[i2 + 12 >> 2] = i2; 7670 HEAP32[i2 + 8 >> 2] = i2; 7671 } 7672 } while (0); 7673 i21 = (HEAP32[88 >> 2] | 0) + -1 | 0; 7674 HEAP32[88 >> 2] = i21; 7675 if ((i21 | 0) == 0) { 7676 i2 = 512 | 0; 7677 } else { 7678 STACKTOP = i1; 7679 return; 7680 } 7681 while (1) { 7682 i2 = HEAP32[i2 >> 2] | 0; 7683 if ((i2 | 0) == 0) { 7684 break; 7685 } else { 7686 i2 = i2 + 8 | 0; 7687 } 7688 } 7689 HEAP32[88 >> 2] = -1; 7690 STACKTOP = i1; 7691 return; 7692} 7693function __Z15fannkuch_workerPv(i9) { 7694 i9 = i9 | 0; 7695 var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0; 7696 i3 = STACKTOP; 7697 i7 = HEAP32[i9 + 4 >> 2] | 0; 7698 i6 = i7 << 2; 7699 i5 = _malloc(i6) | 0; 7700 i2 = _malloc(i6) | 0; 7701 i6 = _malloc(i6) | 0; 7702 i10 = (i7 | 0) > 0; 7703 if (i10) { 7704 i8 = 0; 7705 do { 7706 HEAP32[i5 + (i8 << 2) >> 2] = i8; 7707 i8 = i8 + 1 | 0; 7708 } while ((i8 | 0) != (i7 | 0)); 7709 i8 = i7 + -1 | 0; 7710 i17 = HEAP32[i9 >> 2] | 0; 7711 HEAP32[i5 + (i17 << 2) >> 2] = i8; 7712 i9 = i5 + (i8 << 2) | 0; 7713 HEAP32[i9 >> 2] = i17; 7714 if (i10) { 7715 i10 = i7 << 2; 7716 i11 = 0; 7717 i12 = i7; 7718 L7 : while (1) { 7719 if ((i12 | 0) > 1) { 7720 while (1) { 7721 i13 = i12 + -1 | 0; 7722 HEAP32[i6 + (i13 << 2) >> 2] = i12; 7723 if ((i13 | 0) > 1) { 7724 i12 = i13; 7725 } else { 7726 i12 = 1; 7727 break; 7728 } 7729 } 7730 } 7731 i13 = HEAP32[i5 >> 2] | 0; 7732 if ((i13 | 0) != 0 ? (HEAP32[i9 >> 2] | 0) != (i8 | 0) : 0) { 7733 _memcpy(i2 | 0, i5 | 0, i10 | 0) | 0; 7734 i15 = 0; 7735 i14 = HEAP32[i2 >> 2] | 0; 7736 while (1) { 7737 i17 = i14 + -1 | 0; 7738 if ((i17 | 0) > 1) { 7739 i16 = 1; 7740 do { 7741 i20 = i2 + (i16 << 2) | 0; 7742 i19 = HEAP32[i20 >> 2] | 0; 7743 i18 = i2 + (i17 << 2) | 0; 7744 HEAP32[i20 >> 2] = HEAP32[i18 >> 2]; 7745 HEAP32[i18 >> 2] = i19; 7746 i16 = i16 + 1 | 0; 7747 i17 = i17 + -1 | 0; 7748 } while ((i16 | 0) < (i17 | 0)); 7749 } 7750 i15 = i15 + 1 | 0; 7751 i20 = i2 + (i14 << 2) | 0; 7752 i16 = HEAP32[i20 >> 2] | 0; 7753 HEAP32[i20 >> 2] = i14; 7754 if ((i16 | 0) == 0) { 7755 break; 7756 } else { 7757 i14 = i16; 7758 } 7759 } 7760 i11 = (i11 | 0) < (i15 | 0) ? i15 : i11; 7761 } 7762 if ((i12 | 0) >= (i8 | 0)) { 7763 i8 = 34; 7764 break; 7765 } 7766 while (1) { 7767 if ((i12 | 0) > 0) { 7768 i14 = 0; 7769 while (1) { 7770 i15 = i14 + 1 | 0; 7771 HEAP32[i5 + (i14 << 2) >> 2] = HEAP32[i5 + (i15 << 2) >> 2]; 7772 if ((i15 | 0) == (i12 | 0)) { 7773 i14 = i12; 7774 break; 7775 } else { 7776 i14 = i15; 7777 } 7778 } 7779 } else { 7780 i14 = 0; 7781 } 7782 HEAP32[i5 + (i14 << 2) >> 2] = i13; 7783 i14 = i6 + (i12 << 2) | 0; 7784 i20 = (HEAP32[i14 >> 2] | 0) + -1 | 0; 7785 HEAP32[i14 >> 2] = i20; 7786 i14 = i12 + 1 | 0; 7787 if ((i20 | 0) > 0) { 7788 continue L7; 7789 } 7790 if ((i14 | 0) >= (i8 | 0)) { 7791 i8 = 34; 7792 break L7; 7793 } 7794 i13 = HEAP32[i5 >> 2] | 0; 7795 i12 = i14; 7796 } 7797 } 7798 if ((i8 | 0) == 34) { 7799 _free(i5); 7800 _free(i2); 7801 _free(i6); 7802 STACKTOP = i3; 7803 return i11 | 0; 7804 } 7805 } else { 7806 i1 = i9; 7807 i4 = i8; 7808 } 7809 } else { 7810 i4 = i7 + -1 | 0; 7811 i20 = HEAP32[i9 >> 2] | 0; 7812 HEAP32[i5 + (i20 << 2) >> 2] = i4; 7813 i1 = i5 + (i4 << 2) | 0; 7814 HEAP32[i1 >> 2] = i20; 7815 } 7816 i11 = 0; 7817 L36 : while (1) { 7818 if ((i7 | 0) > 1) { 7819 while (1) { 7820 i8 = i7 + -1 | 0; 7821 HEAP32[i6 + (i8 << 2) >> 2] = i7; 7822 if ((i8 | 0) > 1) { 7823 i7 = i8; 7824 } else { 7825 i7 = 1; 7826 break; 7827 } 7828 } 7829 } 7830 i8 = HEAP32[i5 >> 2] | 0; 7831 if ((i8 | 0) != 0 ? (HEAP32[i1 >> 2] | 0) != (i4 | 0) : 0) { 7832 i10 = 0; 7833 i9 = HEAP32[i2 >> 2] | 0; 7834 while (1) { 7835 i13 = i9 + -1 | 0; 7836 if ((i13 | 0) > 1) { 7837 i12 = 1; 7838 do { 7839 i18 = i2 + (i12 << 2) | 0; 7840 i19 = HEAP32[i18 >> 2] | 0; 7841 i20 = i2 + (i13 << 2) | 0; 7842 HEAP32[i18 >> 2] = HEAP32[i20 >> 2]; 7843 HEAP32[i20 >> 2] = i19; 7844 i12 = i12 + 1 | 0; 7845 i13 = i13 + -1 | 0; 7846 } while ((i12 | 0) < (i13 | 0)); 7847 } 7848 i10 = i10 + 1 | 0; 7849 i20 = i2 + (i9 << 2) | 0; 7850 i12 = HEAP32[i20 >> 2] | 0; 7851 HEAP32[i20 >> 2] = i9; 7852 if ((i12 | 0) == 0) { 7853 break; 7854 } else { 7855 i9 = i12; 7856 } 7857 } 7858 i11 = (i11 | 0) < (i10 | 0) ? i10 : i11; 7859 } 7860 if ((i7 | 0) >= (i4 | 0)) { 7861 i8 = 34; 7862 break; 7863 } 7864 while (1) { 7865 if ((i7 | 0) > 0) { 7866 i9 = 0; 7867 while (1) { 7868 i10 = i9 + 1 | 0; 7869 HEAP32[i5 + (i9 << 2) >> 2] = HEAP32[i5 + (i10 << 2) >> 2]; 7870 if ((i10 | 0) == (i7 | 0)) { 7871 i9 = i7; 7872 break; 7873 } else { 7874 i9 = i10; 7875 } 7876 } 7877 } else { 7878 i9 = 0; 7879 } 7880 HEAP32[i5 + (i9 << 2) >> 2] = i8; 7881 i9 = i6 + (i7 << 2) | 0; 7882 i20 = (HEAP32[i9 >> 2] | 0) + -1 | 0; 7883 HEAP32[i9 >> 2] = i20; 7884 i9 = i7 + 1 | 0; 7885 if ((i20 | 0) > 0) { 7886 continue L36; 7887 } 7888 if ((i9 | 0) >= (i4 | 0)) { 7889 i8 = 34; 7890 break L36; 7891 } 7892 i8 = HEAP32[i5 >> 2] | 0; 7893 i7 = i9; 7894 } 7895 } 7896 if ((i8 | 0) == 34) { 7897 _free(i5); 7898 _free(i2); 7899 _free(i6); 7900 STACKTOP = i3; 7901 return i11 | 0; 7902 } 7903 return 0; 7904} 7905function _main(i3, i5) { 7906 i3 = i3 | 0; 7907 i5 = i5 | 0; 7908 var i1 = 0, i2 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0; 7909 i2 = STACKTOP; 7910 STACKTOP = STACKTOP + 16 | 0; 7911 i1 = i2; 7912 L1 : do { 7913 if ((i3 | 0) > 1) { 7914 i3 = HEAP8[HEAP32[i5 + 4 >> 2] | 0] | 0; 7915 switch (i3 | 0) { 7916 case 50: 7917 { 7918 i3 = 10; 7919 break L1; 7920 } 7921 case 51: 7922 { 7923 i4 = 4; 7924 break L1; 7925 } 7926 case 52: 7927 { 7928 i3 = 11; 7929 break L1; 7930 } 7931 case 53: 7932 { 7933 i3 = 12; 7934 break L1; 7935 } 7936 case 49: 7937 { 7938 i3 = 9; 7939 break L1; 7940 } 7941 case 48: 7942 { 7943 i11 = 0; 7944 STACKTOP = i2; 7945 return i11 | 0; 7946 } 7947 default: 7948 { 7949 HEAP32[i1 >> 2] = i3 + -48; 7950 _printf(8, i1 | 0) | 0; 7951 i11 = -1; 7952 STACKTOP = i2; 7953 return i11 | 0; 7954 } 7955 } 7956 } else { 7957 i4 = 4; 7958 } 7959 } while (0); 7960 if ((i4 | 0) == 4) { 7961 i3 = 11; 7962 } 7963 i5 = i3 + -1 | 0; 7964 i6 = 0; 7965 i7 = 0; 7966 while (1) { 7967 i4 = _malloc(12) | 0; 7968 HEAP32[i4 >> 2] = i7; 7969 HEAP32[i4 + 4 >> 2] = i3; 7970 HEAP32[i4 + 8 >> 2] = i6; 7971 i7 = i7 + 1 | 0; 7972 if ((i7 | 0) == (i5 | 0)) { 7973 break; 7974 } else { 7975 i6 = i4; 7976 } 7977 } 7978 i5 = i3 << 2; 7979 i6 = _malloc(i5) | 0; 7980 i5 = _malloc(i5) | 0; 7981 i7 = 0; 7982 do { 7983 HEAP32[i6 + (i7 << 2) >> 2] = i7; 7984 i7 = i7 + 1 | 0; 7985 } while ((i7 | 0) != (i3 | 0)); 7986 i8 = i3; 7987 i7 = 30; 7988 L19 : do { 7989 i9 = 0; 7990 do { 7991 HEAP32[i1 >> 2] = (HEAP32[i6 + (i9 << 2) >> 2] | 0) + 1; 7992 _printf(48, i1 | 0) | 0; 7993 i9 = i9 + 1 | 0; 7994 } while ((i9 | 0) != (i3 | 0)); 7995 _putchar(10) | 0; 7996 i7 = i7 + -1 | 0; 7997 if ((i8 | 0) <= 1) { 7998 if ((i8 | 0) == (i3 | 0)) { 7999 break; 8000 } 8001 } else { 8002 while (1) { 8003 i9 = i8 + -1 | 0; 8004 HEAP32[i5 + (i9 << 2) >> 2] = i8; 8005 if ((i9 | 0) > 1) { 8006 i8 = i9; 8007 } else { 8008 i8 = 1; 8009 break; 8010 } 8011 } 8012 } 8013 while (1) { 8014 i9 = HEAP32[i6 >> 2] | 0; 8015 if ((i8 | 0) > 0) { 8016 i11 = 0; 8017 while (1) { 8018 i10 = i11 + 1 | 0; 8019 HEAP32[i6 + (i11 << 2) >> 2] = HEAP32[i6 + (i10 << 2) >> 2]; 8020 if ((i10 | 0) == (i8 | 0)) { 8021 i10 = i8; 8022 break; 8023 } else { 8024 i11 = i10; 8025 } 8026 } 8027 } else { 8028 i10 = 0; 8029 } 8030 HEAP32[i6 + (i10 << 2) >> 2] = i9; 8031 i9 = i5 + (i8 << 2) | 0; 8032 i11 = (HEAP32[i9 >> 2] | 0) + -1 | 0; 8033 HEAP32[i9 >> 2] = i11; 8034 i9 = i8 + 1 | 0; 8035 if ((i11 | 0) > 0) { 8036 break; 8037 } 8038 if ((i9 | 0) == (i3 | 0)) { 8039 break L19; 8040 } else { 8041 i8 = i9; 8042 } 8043 } 8044 } while ((i7 | 0) != 0); 8045 _free(i6); 8046 _free(i5); 8047 if ((i4 | 0) == 0) { 8048 i5 = 0; 8049 } else { 8050 i5 = 0; 8051 while (1) { 8052 i6 = __Z15fannkuch_workerPv(i4) | 0; 8053 i5 = (i5 | 0) < (i6 | 0) ? i6 : i5; 8054 i6 = HEAP32[i4 + 8 >> 2] | 0; 8055 _free(i4); 8056 if ((i6 | 0) == 0) { 8057 break; 8058 } else { 8059 i4 = i6; 8060 } 8061 } 8062 } 8063 HEAP32[i1 >> 2] = i3; 8064 HEAP32[i1 + 4 >> 2] = i5; 8065 _printf(24, i1 | 0) | 0; 8066 i11 = 0; 8067 STACKTOP = i2; 8068 return i11 | 0; 8069} 8070function _memcpy(i3, i2, i1) { 8071 i3 = i3 | 0; 8072 i2 = i2 | 0; 8073 i1 = i1 | 0; 8074 var i4 = 0; 8075 if ((i1 | 0) >= 4096) return _emscripten_memcpy_big(i3 | 0, i2 | 0, i1 | 0) | 0; 8076 i4 = i3 | 0; 8077 if ((i3 & 3) == (i2 & 3)) { 8078 while (i3 & 3) { 8079 if ((i1 | 0) == 0) return i4 | 0; 8080 HEAP8[i3] = HEAP8[i2] | 0; 8081 i3 = i3 + 1 | 0; 8082 i2 = i2 + 1 | 0; 8083 i1 = i1 - 1 | 0; 8084 } 8085 while ((i1 | 0) >= 4) { 8086 HEAP32[i3 >> 2] = HEAP32[i2 >> 2]; 8087 i3 = i3 + 4 | 0; 8088 i2 = i2 + 4 | 0; 8089 i1 = i1 - 4 | 0; 8090 } 8091 } 8092 while ((i1 | 0) > 0) { 8093 HEAP8[i3] = HEAP8[i2] | 0; 8094 i3 = i3 + 1 | 0; 8095 i2 = i2 + 1 | 0; 8096 i1 = i1 - 1 | 0; 8097 } 8098 return i4 | 0; 8099} 8100function _memset(i1, i4, i3) { 8101 i1 = i1 | 0; 8102 i4 = i4 | 0; 8103 i3 = i3 | 0; 8104 var i2 = 0, i5 = 0, i6 = 0, i7 = 0; 8105 i2 = i1 + i3 | 0; 8106 if ((i3 | 0) >= 20) { 8107 i4 = i4 & 255; 8108 i7 = i1 & 3; 8109 i6 = i4 | i4 << 8 | i4 << 16 | i4 << 24; 8110 i5 = i2 & ~3; 8111 if (i7) { 8112 i7 = i1 + 4 - i7 | 0; 8113 while ((i1 | 0) < (i7 | 0)) { 8114 HEAP8[i1] = i4; 8115 i1 = i1 + 1 | 0; 8116 } 8117 } 8118 while ((i1 | 0) < (i5 | 0)) { 8119 HEAP32[i1 >> 2] = i6; 8120 i1 = i1 + 4 | 0; 8121 } 8122 } 8123 while ((i1 | 0) < (i2 | 0)) { 8124 HEAP8[i1] = i4; 8125 i1 = i1 + 1 | 0; 8126 } 8127 return i1 - i3 | 0; 8128} 8129function copyTempDouble(i1) { 8130 i1 = i1 | 0; 8131 HEAP8[tempDoublePtr] = HEAP8[i1]; 8132 HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0]; 8133 HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0]; 8134 HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0]; 8135 HEAP8[tempDoublePtr + 4 | 0] = HEAP8[i1 + 4 | 0]; 8136 HEAP8[tempDoublePtr + 5 | 0] = HEAP8[i1 + 5 | 0]; 8137 HEAP8[tempDoublePtr + 6 | 0] = HEAP8[i1 + 6 | 0]; 8138 HEAP8[tempDoublePtr + 7 | 0] = HEAP8[i1 + 7 | 0]; 8139} 8140function copyTempFloat(i1) { 8141 i1 = i1 | 0; 8142 HEAP8[tempDoublePtr] = HEAP8[i1]; 8143 HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0]; 8144 HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0]; 8145 HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0]; 8146} 8147function runPostSets() {} 8148function _strlen(i1) { 8149 i1 = i1 | 0; 8150 var i2 = 0; 8151 i2 = i1; 8152 while (HEAP8[i2] | 0) { 8153 i2 = i2 + 1 | 0; 8154 } 8155 return i2 - i1 | 0; 8156} 8157function stackAlloc(i1) { 8158 i1 = i1 | 0; 8159 var i2 = 0; 8160 i2 = STACKTOP; 8161 STACKTOP = STACKTOP + i1 | 0; 8162 STACKTOP = STACKTOP + 7 & -8; 8163 return i2 | 0; 8164} 8165function setThrew(i1, i2) { 8166 i1 = i1 | 0; 8167 i2 = i2 | 0; 8168 if ((__THREW__ | 0) == 0) { 8169 __THREW__ = i1; 8170 threwValue = i2; 8171 } 8172} 8173function stackRestore(i1) { 8174 i1 = i1 | 0; 8175 STACKTOP = i1; 8176} 8177function setTempRet9(i1) { 8178 i1 = i1 | 0; 8179 tempRet9 = i1; 8180} 8181function setTempRet8(i1) { 8182 i1 = i1 | 0; 8183 tempRet8 = i1; 8184} 8185function setTempRet7(i1) { 8186 i1 = i1 | 0; 8187 tempRet7 = i1; 8188} 8189function setTempRet6(i1) { 8190 i1 = i1 | 0; 8191 tempRet6 = i1; 8192} 8193function setTempRet5(i1) { 8194 i1 = i1 | 0; 8195 tempRet5 = i1; 8196} 8197function setTempRet4(i1) { 8198 i1 = i1 | 0; 8199 tempRet4 = i1; 8200} 8201function setTempRet3(i1) { 8202 i1 = i1 | 0; 8203 tempRet3 = i1; 8204} 8205function setTempRet2(i1) { 8206 i1 = i1 | 0; 8207 tempRet2 = i1; 8208} 8209function setTempRet1(i1) { 8210 i1 = i1 | 0; 8211 tempRet1 = i1; 8212} 8213function setTempRet0(i1) { 8214 i1 = i1 | 0; 8215 tempRet0 = i1; 8216} 8217function stackSave() { 8218 return STACKTOP | 0; 8219} 8220 8221// EMSCRIPTEN_END_FUNCS 8222 8223 8224 return { _strlen: _strlen, _free: _free, _main: _main, _memset: _memset, _malloc: _malloc, _memcpy: _memcpy, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, setThrew: setThrew, setTempRet0: setTempRet0, setTempRet1: setTempRet1, setTempRet2: setTempRet2, setTempRet3: setTempRet3, setTempRet4: setTempRet4, setTempRet5: setTempRet5, setTempRet6: setTempRet6, setTempRet7: setTempRet7, setTempRet8: setTempRet8, setTempRet9: setTempRet9 }; 8225}) 8226// EMSCRIPTEN_END_ASM 8227({ "Math": Math, "Int8Array": Int8Array, "Int16Array": Int16Array, "Int32Array": Int32Array, "Uint8Array": Uint8Array, "Uint16Array": Uint16Array, "Uint32Array": Uint32Array, "Float32Array": Float32Array, "Float64Array": Float64Array }, { "abort": abort, "assert": assert, "asmPrintInt": asmPrintInt, "asmPrintFloat": asmPrintFloat, "min": Math_min, "_fflush": _fflush, "_emscripten_memcpy_big": _emscripten_memcpy_big, "_putchar": _putchar, "_fputc": _fputc, "_send": _send, "_pwrite": _pwrite, "_abort": _abort, "__reallyNegative": __reallyNegative, "_fwrite": _fwrite, "_sbrk": _sbrk, "_mkport": _mkport, "_fprintf": _fprintf, "___setErrNo": ___setErrNo, "__formatString": __formatString, "_fileno": _fileno, "_printf": _printf, "_time": _time, "_sysconf": _sysconf, "_write": _write, "___errno_location": ___errno_location, "STACKTOP": STACKTOP, "STACK_MAX": STACK_MAX, "tempDoublePtr": tempDoublePtr, "ABORT": ABORT, "NaN": NaN, "Infinity": Infinity }, buffer); 8228var _strlen = Module["_strlen"] = asm["_strlen"]; 8229var _free = Module["_free"] = asm["_free"]; 8230var _main = Module["_main"] = asm["_main"]; 8231var _memset = Module["_memset"] = asm["_memset"]; 8232var _malloc = Module["_malloc"] = asm["_malloc"]; 8233var _memcpy = Module["_memcpy"] = asm["_memcpy"]; 8234var runPostSets = Module["runPostSets"] = asm["runPostSets"]; 8235 8236Runtime.stackAlloc = function(size) { return asm['stackAlloc'](size) }; 8237Runtime.stackSave = function() { return asm['stackSave']() }; 8238Runtime.stackRestore = function(top) { asm['stackRestore'](top) }; 8239 8240 8241// Warning: printing of i64 values may be slightly rounded! No deep i64 math used, so precise i64 code not included 8242var i64Math = null; 8243 8244// === Auto-generated postamble setup entry stuff === 8245 8246if (memoryInitializer) { 8247 if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) { 8248 var data = Module['readBinary'](memoryInitializer); 8249 HEAPU8.set(data, STATIC_BASE); 8250 } else { 8251 addRunDependency('memory initializer'); 8252 Browser.asyncLoad(memoryInitializer, function(data) { 8253 HEAPU8.set(data, STATIC_BASE); 8254 removeRunDependency('memory initializer'); 8255 }, function(data) { 8256 throw 'could not load memory initializer ' + memoryInitializer; 8257 }); 8258 } 8259} 8260 8261function ExitStatus(status) { 8262 this.name = "ExitStatus"; 8263 this.message = "Program terminated with exit(" + status + ")"; 8264 this.status = status; 8265}; 8266ExitStatus.prototype = new Error(); 8267ExitStatus.prototype.constructor = ExitStatus; 8268 8269var initialStackTop; 8270var preloadStartTime = null; 8271var calledMain = false; 8272 8273dependenciesFulfilled = function runCaller() { 8274 // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false) 8275 if (!Module['calledRun'] && shouldRunNow) run([].concat(Module["arguments"])); 8276 if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled 8277} 8278 8279Module['callMain'] = Module.callMain = function callMain(args) { 8280 assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)'); 8281 assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called'); 8282 8283 args = args || []; 8284 8285 ensureInitRuntime(); 8286 8287 var argc = args.length+1; 8288 function pad() { 8289 for (var i = 0; i < 4-1; i++) { 8290 argv.push(0); 8291 } 8292 } 8293 var argv = [allocate(intArrayFromString("/bin/this.program"), 'i8', ALLOC_NORMAL) ]; 8294 pad(); 8295 for (var i = 0; i < argc-1; i = i + 1) { 8296 argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL)); 8297 pad(); 8298 } 8299 argv.push(0); 8300 argv = allocate(argv, 'i32', ALLOC_NORMAL); 8301 8302 initialStackTop = STACKTOP; 8303 8304 try { 8305 8306 var ret = Module['_main'](argc, argv, 0); 8307 8308 8309 // if we're not running an evented main loop, it's time to exit 8310 if (!Module['noExitRuntime']) { 8311 exit(ret); 8312 } 8313 } 8314 catch(e) { 8315 if (e instanceof ExitStatus) { 8316 // exit() throws this once it's done to make sure execution 8317 // has been stopped completely 8318 return; 8319 } else if (e == 'SimulateInfiniteLoop') { 8320 // running an evented main loop, don't immediately exit 8321 Module['noExitRuntime'] = true; 8322 return; 8323 } else { 8324 if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]); 8325 throw e; 8326 } 8327 } finally { 8328 calledMain = true; 8329 } 8330} 8331 8332 8333 8334 8335function run(args) { 8336 args = args || Module['arguments']; 8337 8338 if (preloadStartTime === null) preloadStartTime = Date.now(); 8339 8340 if (runDependencies > 0) { 8341 Module.printErr('run() called, but dependencies remain, so not running'); 8342 return; 8343 } 8344 8345 preRun(); 8346 8347 if (runDependencies > 0) return; // a preRun added a dependency, run will be called later 8348 if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame 8349 8350 function doRun() { 8351 if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening 8352 Module['calledRun'] = true; 8353 8354 ensureInitRuntime(); 8355 8356 preMain(); 8357 8358 if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) { 8359 Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms'); 8360 } 8361 8362 if (Module['_main'] && shouldRunNow) { 8363 Module['callMain'](args); 8364 } 8365 8366 postRun(); 8367 } 8368 8369 if (Module['setStatus']) { 8370 Module['setStatus']('Running...'); 8371 setTimeout(function() { 8372 setTimeout(function() { 8373 Module['setStatus'](''); 8374 }, 1); 8375 if (!ABORT) doRun(); 8376 }, 1); 8377 } else { 8378 doRun(); 8379 } 8380} 8381Module['run'] = Module.run = run; 8382 8383function exit(status) { 8384 ABORT = true; 8385 EXITSTATUS = status; 8386 STACKTOP = initialStackTop; 8387 8388 // exit the runtime 8389 exitRuntime(); 8390 8391 // TODO We should handle this differently based on environment. 8392 // In the browser, the best we can do is throw an exception 8393 // to halt execution, but in node we could process.exit and 8394 // I'd imagine SM shell would have something equivalent. 8395 // This would let us set a proper exit status (which 8396 // would be great for checking test exit statuses). 8397 // https://github.com/kripken/emscripten/issues/1371 8398 8399 // throw an exception to halt the current execution 8400 throw new ExitStatus(status); 8401} 8402Module['exit'] = Module.exit = exit; 8403 8404function abort(text) { 8405 if (text) { 8406 Module.print(text); 8407 Module.printErr(text); 8408 } 8409 8410 ABORT = true; 8411 EXITSTATUS = 1; 8412 8413 var extra = '\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.'; 8414 8415 throw 'abort() at ' + stackTrace() + extra; 8416} 8417Module['abort'] = Module.abort = abort; 8418 8419// {{PRE_RUN_ADDITIONS}} 8420 8421if (Module['preInit']) { 8422 if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']]; 8423 while (Module['preInit'].length > 0) { 8424 Module['preInit'].pop()(); 8425 } 8426} 8427 8428// shouldRunNow refers to calling main(), not run(). 8429var shouldRunNow = true; 8430if (Module['noInitialRun']) { 8431 shouldRunNow = false; 8432} 8433 8434 8435run([].concat(Module["arguments"])); 8436