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