Skip to content

Instantly share code, notes, and snippets.

@ziz

ziz/emcc-0-ll.js Secret

Created January 3, 2012 23:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ziz/22eda2059ac6d3af2b7a to your computer and use it in GitHub Desktop.
Save ziz/22eda2059ac6d3af2b7a to your computer and use it in GitHub Desktop.
; ModuleID = '/var/folders/3l/kh8mjcln3s90hm6q5pswr6mc0000gn/T/tmpQgf6v4/a.out.bc'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
target triple = "i386-pc-linux-gnu"
@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00", align 1 ; [#uses=1 type=[15 x i8]*]
; [#uses=0]
define i32 @main() nounwind ssp {
%1 = alloca i32, align 4 ; [#uses=1 type=i32*]
store i32 0, i32* %1
%2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0 type=i32]
ret i32 1
}
; [#uses=1]
declare i32 @printf(i8*, ...)
// Note: Some Emscripten settings will significantly limit the speed of the generated code.
// Note: Some Emscripten settings may limit the speed of the generated code.
// TODO: " u s e s t r i c t ";
// *** Environment setup code ***
var arguments_ = [];
var ENVIRONMENT_IS_NODE = typeof process === 'object';
var ENVIRONMENT_IS_WEB = typeof window === 'object';
var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
if (ENVIRONMENT_IS_NODE) {
// Expose functionality in the same simple way that the shells work
print = function(x) {
process['stdout'].write(x + '\n');
};
printErr = function(x) {
process['stderr'].write(x + '\n');
};
var nodeFS = require('fs');
read = function(filename) {
var ret = nodeFS['readFileSync'](filename).toString();
if (!ret && filename[0] != '/') {
filename = __dirname.split('/').slice(0, -1).join('/') + '/src/' + filename;
ret = nodeFS['readFileSync'](filename).toString();
}
return ret;
};
arguments_ = process['argv'].slice(2);
} else if (ENVIRONMENT_IS_SHELL) {
// Polyfill over SpiderMonkey/V8 differences
if (!this['read']) {
read = function(f) { snarf(f) };
}
if (!this['arguments']) {
arguments_ = scriptArgs;
} else {
arguments_ = arguments;
}
} else if (ENVIRONMENT_IS_WEB) {
print = printErr = function(x) {
console.log(x);
};
read = function(url) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.send(null);
return xhr.responseText;
};
if (this['arguments']) {
arguments_ = arguments;
}
} else if (ENVIRONMENT_IS_WORKER) {
// We can do very little here...
load = importScripts;
} else {
throw 'Unknown runtime environment. Where are we?';
}
function globalEval(x) {
eval.call(null, x);
}
if (typeof load == 'undefined' && typeof read != 'undefined') {
load = function(f) {
globalEval(read(f));
};
}
if (typeof printErr === 'undefined') {
printErr = function(){};
}
if (typeof print === 'undefined') {
print = printErr;
}
// *** Environment setup code ***
try {
this['Module'] = Module;
} catch(e) {
this['Module'] = Module = {};
}
if (!Module.arguments) {
Module.arguments = arguments_;
}
if (Module.print) {
print = Module.print;
}
// === Auto-generated preamble library stuff ===
//========================================
// Runtime code shared with compiler
//========================================
var Runtime = {
stackSave: function () {
return STACKTOP;
},
stackRestore: function (stackTop) {
STACKTOP = stackTop;
},
forceAlign: function (target, quantum) {
quantum = quantum || 4;
if (isNumber(target) && isNumber(quantum)) {
return Math.ceil(target/quantum)*quantum;
} else {
return 'Math.ceil((' + target + ')/' + quantum + ')*' + quantum;
}
},
isNumberType: function (type) {
return type in Runtime.INT_TYPES || type in Runtime.FLOAT_TYPES;
},
isPointerType: function isPointerType(type) {
return type[type.length-1] == '*';
},
isStructType: function isStructType(type) {
if (isPointerType(type)) return false;
if (/^\[\d+\ x\ (.*)\]/.test(type)) return true; // [15 x ?] blocks. Like structs
if (/<?{ [^}]* }>?/.test(type)) return true; // { i32, i8 } etc. - anonymous struct types
// See comment in isStructPointerType()
return type[0] == '%';
},
INT_TYPES: {"i1":0,"i8":0,"i16":0,"i32":0,"i64":0},
FLOAT_TYPES: {"float":0,"double":0},
or64: function (x, y) {
var l = (x | 0) | (y | 0);
var h = (Math.round(x / 4294967296) | Math.round(y / 4294967296)) * 4294967296;
return l + h;
},
and64: function (x, y) {
var l = (x | 0) & (y | 0);
var h = (Math.round(x / 4294967296) & Math.round(y / 4294967296)) * 4294967296;
return l + h;
},
xor64: function (x, y) {
var l = (x | 0) ^ (y | 0);
var h = (Math.round(x / 4294967296) ^ Math.round(y / 4294967296)) * 4294967296;
return l + h;
},
getNativeTypeSize: function (type, quantumSize) {
if (Runtime.QUANTUM_SIZE == 1) return 1;
var size = {
'%i1': 1,
'%i8': 1,
'%i16': 2,
'%i32': 4,
'%i64': 8,
"%float": 4,
"%double": 8
}['%'+type]; // add '%' since float and double confuse Closure compiler as keys, and also spidermonkey as a compiler will remove 's from '_i8' etc
if (!size && type[type.length-1] == '*') {
size = Runtime.QUANTUM_SIZE; // A pointer
}
return size;
},
getNativeFieldSize: function (type) {
return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE);
},
dedup: function dedup(items, ident) {
var seen = {};
if (ident) {
return items.filter(function(item) {
if (seen[item[ident]]) return false;
seen[item[ident]] = true;
return true;
});
} else {
return items.filter(function(item) {
if (seen[item]) return false;
seen[item] = true;
return true;
});
}
},
set: function set() {
var args = typeof arguments[0] === 'object' ? arguments[0] : arguments;
var ret = {};
for (var i = 0; i < args.length; i++) {
ret[args[i]] = 0;
}
return ret;
},
calculateStructAlignment: function calculateStructAlignment(type) {
type.flatSize = 0;
type.alignSize = 0;
var diffs = [];
var prev = -1;
type.flatIndexes = type.fields.map(function(field) {
var size, alignSize;
if (Runtime.isNumberType(field) || Runtime.isPointerType(field)) {
size = Runtime.getNativeTypeSize(field); // pack char; char; in structs, also char[X]s.
alignSize = size;
} else if (Runtime.isStructType(field)) {
size = Types.types[field].flatSize;
alignSize = Types.types[field].alignSize;
} else {
throw 'Unclear type in struct: ' + field + ', in ' + type.name_ + ' :: ' + dump(Types.types[type.name_]);
}
alignSize = type.packed ? 1 : Math.min(alignSize, Runtime.QUANTUM_SIZE);
type.alignSize = Math.max(type.alignSize, alignSize);
var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory
type.flatSize = curr + size;
if (prev >= 0) {
diffs.push(curr-prev);
}
prev = curr;
return curr;
});
type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize);
if (diffs.length == 0) {
type.flatFactor = type.flatSize;
} else if (Runtime.dedup(diffs).length == 1) {
type.flatFactor = diffs[0];
}
type.needsFlattening = (type.flatFactor != 1);
return type.flatIndexes;
},
generateStructInfo: function (struct, typeName, offset) {
var type, alignment;
if (typeName) {
offset = offset || 0;
type = (typeof Types === 'undefined' ? Runtime.typeInfo : Types.types)[typeName];
if (!type) return null;
if (!struct) struct = (typeof Types === 'undefined' ? Runtime : Types).structMetadata[typeName.replace(/.*\./, '')];
if (!struct) return null;
assert(type.fields.length === struct.length, 'Number of named fields must match the type for ' + typeName + '. Perhaps due to inheritance, which is not supported yet?');
alignment = type.flatIndexes;
} else {
var type = { fields: struct.map(function(item) { return item[0] }) };
alignment = Runtime.calculateStructAlignment(type);
}
var ret = {
__size__: type.flatSize
};
if (typeName) {
struct.forEach(function(item, i) {
if (typeof item === 'string') {
ret[item] = alignment[i] + offset;
} else {
// embedded struct
var key;
for (var k in item) key = k;
ret[key] = Runtime.generateStructInfo(item[key], type.fields[i], alignment[i]);
}
});
} else {
struct.forEach(function(item, i) {
ret[item[1]] = alignment[i];
});
}
return ret;
},
stackAlloc: function stackAlloc(size) { var ret = STACKTOP; STACKTOP += size;STACKTOP = Math.ceil((STACKTOP)/4)*4;; assert(STACKTOP < STACK_ROOT + STACK_MAX, "Ran out of stack"); return ret; },
staticAlloc: function staticAlloc(size) { var ret = STATICTOP; STATICTOP += size;STATICTOP = Math.ceil((STATICTOP)/4)*4;; if (STATICTOP >= TOTAL_MEMORY) enlargeMemory();; return ret; },
alignMemory: function alignMemory(size,quantum) { var ret = size = Math.ceil((size)/(quantum ? quantum : 4))*(quantum ? quantum : 4);; return ret; },
QUANTUM_SIZE: 4,
__dummy__: 0
}
var CorrectionsMonitor = {
MAX_ALLOWED: 0, // XXX
corrections: 0,
sigs: {},
note: function(type, succeed, sig) {
if (!succeed) {
this.corrections++;
if (this.corrections >= this.MAX_ALLOWED) abort('\n\nToo many corrections!');
}
},
print: function() {
var items = [];
for (var sig in this.sigs) {
items.push({
sig: sig,
fails: this.sigs[sig][0],
succeeds: this.sigs[sig][1],
total: this.sigs[sig][0] + this.sigs[sig][1]
});
}
items.sort(function(x, y) { return y.total - x.total; });
for (var i = 0; i < items.length; i++) {
var item = items[i];
print(item.sig + ' : ' + item.total + ' hits, %' + (Math.ceil(100*item.fails/item.total)) + ' failures');
}
}
};
//========================================
// Runtime essentials
//========================================
var __globalConstructor__ = function globalConstructor() {
};
var __THREW__ = false; // Used in checking for thrown exceptions.
var __ATEXIT__ = [];
var ABORT = false;
var undef = 0;
// tempInt is used for 32-bit signed values or smaller. tempBigInt is used
// for 32-bit unsigned values or more than 32 bits. TODO: audit all uses of tempInt
var tempValue, tempInt, tempBigInt, tempInt2, tempBigInt2, tempPair, tempBigIntI, tempBigIntR, tempBigIntS, tempBigIntP, tempBigIntD;
var tempI64, tempI64b;
var tempDoubleBuffer = new ArrayBuffer(8);
var tempDoubleI32 = new Int32Array(tempDoubleBuffer);
var tempDoubleF64 = new Float64Array(tempDoubleBuffer);
function abort(text) {
print(text + ':\n' + (new Error).stack);
ABORT = true;
throw "Assertion: " + text;
}
function assert(condition, text) {
if (!condition) {
abort('Assertion failed: ' + text);
}
}
// Sets a value in memory in a dynamic way at run-time. Uses the
// type data. This is the same as makeSetValue, except that
// makeSetValue is done at compile-time and generates the needed
// code then, whereas this function picks the right code at
// run-time.
function setValue(ptr, value, type, noSafe) {
type = type || 'i8';
if (type[type.length-1] === '*') type = 'i32'; // pointers are 32-bit
switch(type) {
case 'i1': HEAP8[(ptr)]=value; break;
case 'i8': HEAP8[(ptr)]=value; break;
case 'i16': HEAP16[((ptr)>>1)]=value; break;
case 'i32': HEAP32[((ptr)>>2)]=value; break;
case 'i64': (HEAP32[((ptr)>>2)]=value[0],HEAP32[((ptr+4)>>2)]=value[1]); break;
case 'float': HEAPF32[((ptr)>>2)]=value; break;
case 'double': (tempDoubleF64[0]=value,HEAP32[((ptr)>>2)]=tempDoubleI32[0],HEAP32[((ptr+4)>>2)]=tempDoubleI32[1]); break;
default: abort('invalid type for setValue: ' + type);
}
}
Module['setValue'] = setValue;
// Parallel to setValue.
function getValue(ptr, type, noSafe) {
type = type || 'i8';
if (type[type.length-1] === '*') type = 'i32'; // pointers are 32-bit
switch(type) {
case 'i1': return HEAP8[(ptr)];
case 'i8': return HEAP8[(ptr)];
case 'i16': return HEAP16[((ptr)>>1)];
case 'i32': return HEAP32[((ptr)>>2)];
case 'i64': return [HEAPU32[((ptr)>>2)],HEAPU32[((ptr+4)>>2)]];
case 'float': return HEAPF32[((ptr)>>2)];
case 'double': return (tempDoubleI32[0]=HEAP32[((ptr)>>2)],tempDoubleI32[1]=HEAP32[((ptr+4)>>2)],tempDoubleF64[0]);
default: abort('invalid type for setValue: ' + type);
}
return null;
}
Module['getValue'] = getValue;
// Allocates memory for some data and initializes it properly.
var ALLOC_NORMAL = 0; // Tries to use _malloc()
var ALLOC_STACK = 1; // Lives for the duration of the current function call
var ALLOC_STATIC = 2; // Cannot be freed
Module['ALLOC_NORMAL'] = ALLOC_NORMAL;
Module['ALLOC_STACK'] = ALLOC_STACK;
Module['ALLOC_STATIC'] = ALLOC_STATIC;
function allocate(slab, types, allocator) {
var zeroinit, size;
if (typeof slab === 'number') {
zeroinit = true;
size = slab;
} else {
zeroinit = false;
size = slab.length;
}
var singleType = typeof types === 'string' ? types : null;
var ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length));
var i = 0, type;
while (i < size) {
var curr = zeroinit ? 0 : slab[i];
if (typeof curr === 'function') {
curr = Runtime.getFunctionIndex(curr);
}
type = singleType || types[i];
if (type === 0) {
i++;
continue;
}
assert(type, 'Must know what type to store in allocate!');
if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later
setValue(ret+i, curr, type);
i += Runtime.getNativeTypeSize(type);
}
return ret;
}
Module['allocate'] = allocate;
function Pointer_stringify(ptr) {
var ret = "";
var i = 0;
var t;
var nullByte = String.fromCharCode(0);
while (1) {
t = String.fromCharCode(HEAPU8[(ptr+i)]);
if (t == nullByte) { break; } else {}
ret += t;
i += 1;
}
return ret;
}
Module['Pointer_stringify'] = Pointer_stringify;
function Array_stringify(array) {
var ret = "";
for (var i = 0; i < array.length; i++) {
ret += String.fromCharCode(array[i]);
}
return ret;
}
Module['Array_stringify'] = Array_stringify;
// Memory management
var FUNCTION_TABLE; // XXX: In theory the indexes here can be equal to pointers to stacked or malloced memory. Such comparisons should
// be false, but can turn out true. We should probably set the top bit to prevent such issues.
var PAGE_SIZE = 4096;
function alignMemoryPage(x) {
return Math.ceil(x/PAGE_SIZE)*PAGE_SIZE;
}
var HEAP;
var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32;
var STACK_ROOT, STACKTOP, STACK_MAX;
var STATICTOP;
function enlargeMemory() {
// TOTAL_MEMORY is the current size of the actual array, and STATICTOP is the new top.
printErr('Warning: Enlarging memory arrays, this is not fast! ' + [STATICTOP, TOTAL_MEMORY]);
assert(STATICTOP >= TOTAL_MEMORY);
assert(TOTAL_MEMORY > 4); // So the loop below will not be infinite
while (TOTAL_MEMORY <= STATICTOP) { // Simple heuristic. Override enlargeMemory() if your program has something more optimal for it
TOTAL_MEMORY = alignMemoryPage(TOTAL_MEMORY*1.25);
}
var oldHEAP8 = HEAP8;
var buffer = new ArrayBuffer(TOTAL_MEMORY);
HEAP8 = new Int8Array(buffer);
HEAP16 = new Int16Array(buffer);
HEAP32 = new Int32Array(buffer);
HEAPU8 = new Uint8Array(buffer);
HEAPU16 = new Uint16Array(buffer);
HEAPU32 = new Uint32Array(buffer);
HEAPF32 = new Float32Array(buffer);
HEAP8.set(oldHEAP8);
}
var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 10485760;
var FAST_MEMORY = Module['FAST_MEMORY'] || 2097152;
// Initialize the runtime's memory
// check for full engine support (use string 'subarray' to avoid closure compiler confusion)
assert(!!Int32Array && !!Float64Array && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']),
'Cannot fallback to non-typed array case: Code is too specialized');
var buffer = new ArrayBuffer(TOTAL_MEMORY);
HEAP8 = new Int8Array(buffer);
HEAP16 = new Int16Array(buffer);
HEAP32 = new Int32Array(buffer);
HEAPU8 = new Uint8Array(buffer);
HEAPU16 = new Uint16Array(buffer);
HEAPU32 = new Uint32Array(buffer);
HEAPF32 = new Float32Array(buffer);
// Endianness check (note: assumes compiler arch was little-endian)
HEAP32[0] = 255;
assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system');
var base = intArrayFromString('(null)'); // So printing %s of NULL gives '(null)'
// Also this ensures we leave 0 as an invalid address, 'NULL'
STATICTOP = base.length;
for (var i = 0; i < base.length; i++) {
HEAP8[(i)]=base[i]
}
Module['HEAP'] = HEAP;
Module['HEAP8'] = HEAP8;
Module['HEAP16'] = HEAP16;
Module['HEAP32'] = HEAP32;
Module['HEAPU8'] = HEAPU8;
Module['HEAPU16'] = HEAPU16;
Module['HEAPU32'] = HEAPU32;
Module['HEAPF32'] = HEAPF32;
STACK_ROOT = STACKTOP = alignMemoryPage(10);
var TOTAL_STACK = 1024*1024; // XXX: Changing this value can lead to bad perf on v8!
STACK_MAX = STACK_ROOT + TOTAL_STACK;
STATICTOP = alignMemoryPage(STACK_MAX);
function __shutdownRuntime__() {
while(__ATEXIT__.length > 0) {
var atexit = __ATEXIT__.pop();
var func = atexit.func;
if (typeof func === 'number') {
func = FUNCTION_TABLE[func];
}
func(atexit.arg === undefined ? null : atexit.arg);
}
// allow browser to GC, set heaps to null?
// Print summary of correction activity
CorrectionsMonitor.print();
}
// Copies a list of num items on the HEAP into a
// a normal JavaScript array of numbers
function Array_copy(ptr, num) {
return Array.prototype.slice.call(HEAP8.subarray(ptr, ptr+num)); // Make a normal array out of the typed 'view'
// Consider making a typed array here, for speed?
return HEAP.slice(ptr, ptr+num);
}
Module['Array_copy'] = Array_copy;
function String_len(ptr) {
var i = 0;
while (HEAP8[(ptr+i)]) i++; // Note: should be |!= 0|, technically. But this helps catch bugs with undefineds
return i;
}
Module['String_len'] = String_len;
// Copies a C-style string, terminated by a zero, from the HEAP into
// a normal JavaScript array of numbers
function String_copy(ptr, addZero) {
var len = String_len(ptr);
if (addZero) len++;
var ret = Array_copy(ptr, len);
if (addZero) ret[len-1] = 0;
return ret;
}
Module['String_copy'] = String_copy;
// Tools
// This processes a JS string into a C-line array of numbers, 0-terminated.
// For LLVM-originating strings, see parser.js:parseLLVMString function
function intArrayFromString(stringy, dontAddNull) {
var ret = [];
var t;
var i = 0;
while (i < stringy.length) {
var chr = stringy.charCodeAt(i);
if (chr > 0xFF) {
assert(false, 'Character code ' + chr + ' (' + stringy[i] + ') at offset ' + i + ' not in 0x00-0xFF.');
chr &= 0xFF;
}
ret.push(chr);
i = i + 1;
}
if (!dontAddNull) {
ret.push(0);
}
return ret;
}
Module['intArrayFromString'] = intArrayFromString;
function intArrayToString(array) {
var ret = [];
for (var i = 0; i < array.length; i++) {
var chr = array[i];
if (chr > 0xFF) {
assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ') at offset ' + i + ' not in 0x00-0xFF.');
chr &= 0xFF;
}
ret.push(String.fromCharCode(chr));
}
return ret.join('');
}
Module['intArrayToString'] = intArrayToString;
function unSign(value, bits, ignore, sig) {
if (value >= 0) {
return value;
}
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
: Math.pow(2, bits) + value;
// TODO: clean up previous line
}
function reSign(value, bits, ignore, sig) {
if (value <= 0) {
return value;
}
var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
: Math.pow(2, bits-1);
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
// but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
// TODO: In i64 mode 1, resign the two parts separately and safely
value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
}
return value;
}
// === Body ===
function _main() {
;
var __label__;
var $1;
$1=0;
var $2=_printf(((__str)|0), allocate(1, "i32", ALLOC_STACK));
;
return 1;
}
Module["_main"] = _main;
var ERRNO_CODES={E2BIG:7,EACCES:13,EADDRINUSE:98,EADDRNOTAVAIL:99,EAFNOSUPPORT:97,EAGAIN:11,EALREADY:114,EBADF:9,EBADMSG:74,EBUSY:16,ECANCELED:125,ECHILD:10,ECONNABORTED:103,ECONNREFUSED:111,ECONNRESET:104,EDEADLK:35,EDESTADDRREQ:89,EDOM:33,EDQUOT:122,EEXIST:17,EFAULT:14,EFBIG:27,EHOSTUNREACH:113,EIDRM:43,EILSEQ:84,EINPROGRESS:115,EINTR:4,EINVAL:22,EIO:5,EISCONN:106,EISDIR:21,ELOOP:40,EMFILE:24,EMLINK:31,EMSGSIZE:90,EMULTIHOP:72,ENAMETOOLONG:36,ENETDOWN:100,ENETRESET:102,ENETUNREACH:101,ENFILE:23,ENOBUFS:105,ENODATA:61,ENODEV:19,ENOENT:2,ENOEXEC:8,ENOLCK:37,ENOLINK:67,ENOMEM:12,ENOMSG:42,ENOPROTOOPT:92,ENOSPC:28,ENOSR:63,ENOSTR:60,ENOSYS:38,ENOTCONN:107,ENOTDIR:20,ENOTEMPTY:39,ENOTRECOVERABLE:131,ENOTSOCK:88,ENOTSUP:95,ENOTTY:25,ENXIO:6,EOVERFLOW:75,EOWNERDEAD:130,EPERM:1,EPIPE:32,EPROTO:71,EPROTONOSUPPORT:93,EPROTOTYPE:91,ERANGE:34,EROFS:30,ESPIPE:29,ESRCH:3,ESTALE:116,ETIME:62,ETIMEDOUT:110,ETXTBSY:26,EWOULDBLOCK:11,EXDEV:18};
function ___setErrNo(value) {
// For convenient setting and returning of errno.
if (!___setErrNo.ret) ___setErrNo.ret = allocate([0], 'i32', ALLOC_STATIC);
HEAP32[((___setErrNo.ret)>>2)]=value
return value;
}
var _stdin=0;
var _stdout=0;
var _stderr=0;
var __impure_ptr=0;var FS={currentPath:"/",nextInode:2,streams:[null],ignorePermissions:true,absolutePath:function (relative, base) {
if (typeof relative !== 'string') return null;
if (base === undefined) base = FS.currentPath;
if (relative && relative[0] == '/') base = '';
var full = base + '/' + relative;
var parts = full.split('/').reverse();
var absolute = [''];
while (parts.length) {
var part = parts.pop();
if (part == '' || part == '.') {
// Nothing.
} else if (part == '..') {
if (absolute.length > 1) absolute.pop();
} else {
absolute.push(part);
}
}
return absolute.length == 1 ? '/' : absolute.join('/');
},analyzePath:function (path, dontResolveLastLink, linksVisited) {
var ret = {
isRoot: false,
exists: false,
error: 0,
name: null,
path: null,
object: null,
parentExists: false,
parentPath: null,
parentObject: null
};
path = FS.absolutePath(path);
if (path == '/') {
ret.isRoot = true;
ret.exists = ret.parentExists = true;
ret.name = '/';
ret.path = ret.parentPath = '/';
ret.object = ret.parentObject = FS.root;
} else if (path !== null) {
linksVisited = linksVisited || 0;
path = path.slice(1).split('/');
var current = FS.root;
var traversed = [''];
while (path.length) {
if (path.length == 1 && current.isFolder) {
ret.parentExists = true;
ret.parentPath = traversed.length == 1 ? '/' : traversed.join('/');
ret.parentObject = current;
ret.name = path[0];
}
var target = path.shift();
if (!current.isFolder) {
ret.error = ERRNO_CODES.ENOTDIR;
break;
} else if (!current.read) {
ret.error = ERRNO_CODES.EACCES;
break;
} else if (!current.contents.hasOwnProperty(target)) {
ret.error = ERRNO_CODES.ENOENT;
break;
}
current = current.contents[target];
if (current.link && !(dontResolveLastLink && path.length == 0)) {
if (linksVisited > 40) { // Usual Linux SYMLOOP_MAX.
ret.error = ERRNO_CODES.ELOOP;
break;
}
var link = FS.absolutePath(current.link, traversed.join('/'));
return FS.analyzePath([link].concat(path).join('/'),
dontResolveLastLink, linksVisited + 1);
}
traversed.push(target);
if (path.length == 0) {
ret.exists = true;
ret.path = traversed.join('/');
ret.object = current;
}
}
return ret;
}
return ret;
},findObject:function (path, dontResolveLastLink) {
FS.ensureRoot();
var ret = FS.analyzePath(path, dontResolveLastLink);
if (ret.exists) {
return ret.object;
} else {
___setErrNo(ret.error);
return null;
}
},createObject:function (parent, name, properties, canRead, canWrite) {
if (!parent) parent = '/';
if (typeof parent === 'string') parent = FS.findObject(parent);
if (!parent) {
___setErrNo(ERRNO_CODES.EACCES);
throw new Error('Parent path must exist.');
}
if (!parent.isFolder) {
___setErrNo(ERRNO_CODES.ENOTDIR);
throw new Error('Parent must be a folder.');
}
if (!parent.write && !FS.ignorePermissions) {
___setErrNo(ERRNO_CODES.EACCES);
throw new Error('Parent folder must be writeable.');
}
if (!name || name == '.' || name == '..') {
___setErrNo(ERRNO_CODES.ENOENT);
throw new Error('Name must not be empty.');
}
if (parent.contents.hasOwnProperty(name)) {
___setErrNo(ERRNO_CODES.EEXIST);
throw new Error("Can't overwrite object.");
}
parent.contents[name] = {
read: canRead === undefined ? true : canRead,
write: canWrite === undefined ? false : canWrite,
timestamp: Date.now(),
inodeNumber: FS.nextInode++
};
for (var key in properties) {
if (properties.hasOwnProperty(key)) {
parent.contents[name][key] = properties[key];
}
}
return parent.contents[name];
},createFolder:function (parent, name, canRead, canWrite) {
var properties = {isFolder: true, isDevice: false, contents: {}};
return FS.createObject(parent, name, properties, canRead, canWrite);
},createPath:function (parent, path, canRead, canWrite) {
var current = FS.findObject(parent);
if (current === null) throw new Error('Invalid parent.');
path = path.split('/').reverse();
while (path.length) {
var part = path.pop();
if (!part) continue;
if (!current.contents.hasOwnProperty(part)) {
FS.createFolder(current, part, canRead, canWrite);
}
current = current.contents[part];
}
return current;
},createFile:function (parent, name, properties, canRead, canWrite) {
properties.isFolder = false;
return FS.createObject(parent, name, properties, canRead, canWrite);
},createDataFile:function (parent, name, data, canRead, canWrite) {
if (typeof data === 'string') {
var dataArray = [];
for (var i = 0; i < data.length; i++) dataArray.push(data.charCodeAt(i));
data = dataArray;
}
var properties = {isDevice: false, contents: data};
return FS.createFile(parent, name, properties, canRead, canWrite);
},createLazyFile:function (parent, name, url, canRead, canWrite) {
var properties = {isDevice: false, url: url};
return FS.createFile(parent, name, properties, canRead, canWrite);
},createLink:function (parent, name, target, canRead, canWrite) {
var properties = {isDevice: false, link: target};
return FS.createFile(parent, name, properties, canRead, canWrite);
},createDevice:function (parent, name, input, output) {
if (!(input || output)) {
throw new Error('A device must have at least one callback defined.');
}
var ops = {isDevice: true, input: input, output: output};
return FS.createFile(parent, name, ops, Boolean(input), Boolean(output));
},forceLoadFile:function (obj) {
if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
var success = true;
if (typeof XMLHttpRequest !== 'undefined') {
// Browser.
// TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
var xhr = new XMLHttpRequest();
xhr.open('GET', obj.url, false);
// Some hints to the browser that we want binary data.
if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer';
if (xhr.overrideMimeType) {
xhr.overrideMimeType('text/plain; charset=x-user-defined');
}
xhr.send(null);
if (xhr.status != 200 && xhr.status != 0) success = false;
if (xhr.response !== undefined) {
obj.contents = new Uint8Array(xhr.response || []);
} else {
obj.contents = intArrayFromString(xhr.responseText || '', true);
}
} else if (typeof read !== 'undefined') {
// Command-line.
try {
// WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
// read() will try to parse UTF8.
obj.contents = intArrayFromString(read(obj.url), true);
} catch (e) {
success = false;
}
} else {
throw new Error('Cannot load without read() or XMLHttpRequest.');
}
if (!success) ___setErrNo(ERRNO_CODES.EIO);
return success;
},ensureRoot:function () {
if (FS.root) return;
// The main file system tree. All the contents are inside this.
FS.root = {
read: true,
write: false,
isFolder: true,
isDevice: false,
timestamp: Date.now(),
inodeNumber: 1,
contents: {}
};
},init:function (input, output, error) {
// Make sure we initialize only once.
if (FS.init.initialized) return;
FS.init.initialized = true;
FS.ensureRoot();
// Default handlers.
if (!input) input = function() {
if (!input.cache || !input.cache.length) {
var result;
if (typeof window != 'undefined' &&
typeof window.prompt == 'function') {
// Browser.
result = window.prompt('Input: ');
} else if (typeof readline == 'function') {
// Command line.
result = readline();
}
if (!result) result = '';
input.cache = intArrayFromString(result + '\n', true);
}
return input.cache.shift();
};
if (!output) output = function(val) {
if (val === null || val === '\n'.charCodeAt(0)) {
output.printer(output.buffer.join(''));
output.buffer = [];
} else {
output.buffer.push(String.fromCharCode(val));
}
};
if (!output.printer) output.printer = print;
if (!output.buffer) output.buffer = [];
if (!error) error = output;
// Create the temporary folder.
FS.createFolder('/', 'tmp', true, true);
// Create the I/O devices.
var devFolder = FS.createFolder('/', 'dev', true, false);
var stdin = FS.createDevice(devFolder, 'stdin', input);
var stdout = FS.createDevice(devFolder, 'stdout', null, output);
var stderr = FS.createDevice(devFolder, 'stderr', null, error);
FS.createDevice(devFolder, 'tty', input, output);
// Create default streams.
FS.streams[1] = {
path: '/dev/stdin',
object: stdin,
position: 0,
isRead: true,
isWrite: false,
isAppend: false,
error: false,
eof: false,
ungotten: []
};
FS.streams[2] = {
path: '/dev/stdout',
object: stdout,
position: 0,
isRead: false,
isWrite: true,
isAppend: false,
error: false,
eof: false,
ungotten: []
};
FS.streams[3] = {
path: '/dev/stderr',
object: stderr,
position: 0,
isRead: false,
isWrite: true,
isAppend: false,
error: false,
eof: false,
ungotten: []
};
_stdin = allocate([1], 'void*', ALLOC_STATIC);
_stdout = allocate([2], 'void*', ALLOC_STATIC);
_stderr = allocate([3], 'void*', ALLOC_STATIC);
// Newlib initialization
FS.streams[_stdin] = FS.streams[1];
FS.streams[_stdout] = FS.streams[2];
FS.streams[_stderr] = FS.streams[3];
__impure_ptr = allocate([ allocate(
[0, 0, 0, 0, _stdin, 0, 0, 0, _stdout, 0, 0, 0, _stderr, 0, 0, 0],
'void*', ALLOC_STATIC) ], 'void*', ALLOC_STATIC);
},quit:function () {
if (!FS.init.initialized) return;
// Flush any partially-printed lines in stdout and stderr
if (FS.streams[2].object.output.buffer.length > 0) FS.streams[2].object.output('\n'.charCodeAt(0));
if (FS.streams[3].object.output.buffer.length > 0) FS.streams[3].object.output('\n'.charCodeAt(0));
}};
function _pwrite(fildes, buf, nbyte, offset) {
// ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
var stream = FS.streams[fildes];
if (!stream || stream.object.isDevice) {
___setErrNo(ERRNO_CODES.EBADF);
return -1;
} else if (!stream.isWrite) {
___setErrNo(ERRNO_CODES.EACCES);
return -1;
} else if (stream.object.isFolder) {
___setErrNo(ERRNO_CODES.EISDIR);
return -1;
} else if (nbyte < 0 || offset < 0) {
___setErrNo(ERRNO_CODES.EINVAL);
return -1;
} else {
var contents = stream.object.contents;
while (contents.length < offset) contents.push(0);
for (var i = 0; i < nbyte; i++) {
contents[offset + i] = HEAPU8[(buf+i)];
}
stream.object.timestamp = Date.now();
return i;
}
}function _write(fildes, buf, nbyte) {
// ssize_t write(int fildes, const void *buf, size_t nbyte);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
var stream = FS.streams[fildes];
if (!stream) {
___setErrNo(ERRNO_CODES.EBADF);
return -1;
} else if (!stream.isWrite) {
___setErrNo(ERRNO_CODES.EACCES);
return -1;
} else if (nbyte < 0) {
___setErrNo(ERRNO_CODES.EINVAL);
return -1;
} else {
if (stream.object.isDevice) {
if (stream.object.output) {
for (var i = 0; i < nbyte; i++) {
try {
stream.object.output(HEAP8[(buf+i)]);
} catch (e) {
___setErrNo(ERRNO_CODES.EIO);
return -1;
}
}
stream.object.timestamp = Date.now();
return i;
} else {
___setErrNo(ERRNO_CODES.ENXIO);
return -1;
}
} else {
var bytesWritten = _pwrite(fildes, buf, nbyte, stream.position);
if (bytesWritten != -1) stream.position += bytesWritten;
return bytesWritten;
}
}
}function _fwrite(ptr, size, nitems, stream) {
// size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html
var bytesToWrite = nitems * size;
if (bytesToWrite == 0) return 0;
var bytesWritten = _write(stream, ptr, bytesToWrite);
if (bytesWritten == -1) {
if (FS.streams[stream]) FS.streams[stream].error = true;
return -1;
} else {
return Math.floor(bytesWritten / size);
}
}
function __formatString(format, varargs) {
var textIndex = format;
var argIndex = 0;
function getNextArg(type) {
// NOTE: Explicitly ignoring type safety. Otherwise this fails:
// int x = 4; printf("%c\n", (char)x);
var ret;
if (type === 'double') {
ret = (tempDoubleI32[0]=HEAP32[((varargs+argIndex)>>2)],tempDoubleI32[1]=HEAP32[((varargs+argIndex+4)>>2)],tempDoubleF64[0]);
} else if (type == 'i64') {
ret = [HEAP32[((varargs+argIndex)>>2)],
HEAP32[((varargs+argIndex+4)>>2)]];
ret = unSign(ret[0], 32) + unSign(ret[1], 32)*Math.pow(2, 32); // Unsigned in this notation. Signed later if needed. // XXX - loss of precision
} else {
type = 'i32'; // varargs are always i32, i64, or double
ret = HEAP32[((varargs+argIndex)>>2)];
}
argIndex += Runtime.getNativeFieldSize(type);
return Number(ret);
}
var ret = [];
var curr, next, currArg;
while(1) {
var startTextIndex = textIndex;
curr = HEAP8[(textIndex)];
if (curr === 0) break;
next = HEAP8[(textIndex+1)];
if (curr == '%'.charCodeAt(0)) {
// Handle flags.
var flagAlwaysSigned = false;
var flagLeftAlign = false;
var flagAlternative = false;
var flagZeroPad = false;
flagsLoop: while (1) {
switch (next) {
case '+'.charCodeAt(0):
flagAlwaysSigned = true;
break;
case '-'.charCodeAt(0):
flagLeftAlign = true;
break;
case '#'.charCodeAt(0):
flagAlternative = true;
break;
case '0'.charCodeAt(0):
if (flagZeroPad) {
break flagsLoop;
} else {
flagZeroPad = true;
break;
}
default:
break flagsLoop;
}
textIndex++;
next = HEAP8[(textIndex+1)];
}
// Handle width.
var width = 0;
if (next == '*'.charCodeAt(0)) {
width = getNextArg('i32');
textIndex++;
next = HEAP8[(textIndex+1)];
} else {
while (next >= '0'.charCodeAt(0) && next <= '9'.charCodeAt(0)) {
width = width * 10 + (next - '0'.charCodeAt(0));
textIndex++;
next = HEAP8[(textIndex+1)];
}
}
// Handle precision.
var precisionSet = false;
if (next == '.'.charCodeAt(0)) {
var precision = 0;
precisionSet = true;
textIndex++;
next = HEAP8[(textIndex+1)];
if (next == '*'.charCodeAt(0)) {
precision = getNextArg('i32');
textIndex++;
} else {
while(1) {
var precisionChr = HEAP8[(textIndex+1)];
if (precisionChr < '0'.charCodeAt(0) ||
precisionChr > '9'.charCodeAt(0)) break;
precision = precision * 10 + (precisionChr - '0'.charCodeAt(0));
textIndex++;
}
}
next = HEAP8[(textIndex+1)];
} else {
var precision = 6; // Standard default.
}
// Handle integer sizes. WARNING: These assume a 32-bit architecture!
var argSize;
switch (String.fromCharCode(next)) {
case 'h':
var nextNext = HEAP8[(textIndex+2)];
if (nextNext == 'h'.charCodeAt(0)) {
textIndex++;
argSize = 1; // char (actually i32 in varargs)
} else {
argSize = 2; // short (actually i32 in varargs)
}
break;
case 'l':
var nextNext = HEAP8[(textIndex+2)];
if (nextNext == 'l'.charCodeAt(0)) {
textIndex++;
argSize = 8; // long long
} else {
argSize = 4; // long
}
break;
case 'L': // long long
case 'q': // int64_t
case 'j': // intmax_t
argSize = 8;
break;
case 'z': // size_t
case 't': // ptrdiff_t
case 'I': // signed ptrdiff_t or unsigned size_t
argSize = 4;
break;
default:
argSize = null;
}
if (argSize) textIndex++;
next = HEAP8[(textIndex+1)];
// Handle type specifier.
if (['d', 'i', 'u', 'o', 'x', 'X', 'p'].indexOf(String.fromCharCode(next)) != -1) {
// Integer.
var signed = next == 'd'.charCodeAt(0) || next == 'i'.charCodeAt(0);
argSize = argSize || 4;
var currArg = getNextArg('i' + (argSize * 8));
// Truncate to requested size.
if (argSize <= 4) {
var limit = Math.pow(256, argSize) - 1;
currArg = (signed ? reSign : unSign)(currArg & limit, argSize * 8);
}
// Format the number.
var currAbsArg = Math.abs(currArg);
var argText;
var prefix = '';
if (next == 'd'.charCodeAt(0) || next == 'i'.charCodeAt(0)) {
argText = reSign(currArg, 8 * argSize, 1).toString(10);
} else if (next == 'u'.charCodeAt(0)) {
argText = unSign(currArg, 8 * argSize, 1).toString(10);
currArg = Math.abs(currArg);
} else if (next == 'o'.charCodeAt(0)) {
argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8);
} else if (next == 'x'.charCodeAt(0) || next == 'X'.charCodeAt(0)) {
prefix = flagAlternative ? '0x' : '';
if (currArg < 0) {
// Represent negative numbers in hex as 2's complement.
currArg = -currArg;
argText = (currAbsArg - 1).toString(16);
var buffer = [];
for (var i = 0; i < argText.length; i++) {
buffer.push((0xF - parseInt(argText[i], 16)).toString(16));
}
argText = buffer.join('');
while (argText.length < argSize * 2) argText = 'f' + argText;
} else {
argText = currAbsArg.toString(16);
}
if (next == 'X'.charCodeAt(0)) {
prefix = prefix.toUpperCase();
argText = argText.toUpperCase();
}
} else if (next == 'p'.charCodeAt(0)) {
if (currAbsArg === 0) {
argText = '(nil)';
} else {
prefix = '0x';
argText = currAbsArg.toString(16);
}
}
if (precisionSet) {
while (argText.length < precision) {
argText = '0' + argText;
}
}
// Add sign if needed
if (flagAlwaysSigned) {
if (currArg < 0) {
prefix = '-' + prefix;
} else {
prefix = '+' + prefix;
}
}
// Add padding.
while (prefix.length + argText.length < width) {
if (flagLeftAlign) {
argText += ' ';
} else {
if (flagZeroPad) {
argText = '0' + argText;
} else {
prefix = ' ' + prefix;
}
}
}
// Insert the result into the buffer.
argText = prefix + argText;
argText.split('').forEach(function(chr) {
ret.push(chr.charCodeAt(0));
});
} else if (['f', 'F', 'e', 'E', 'g', 'G'].indexOf(String.fromCharCode(next)) != -1) {
// Float.
var currArg = getNextArg('double');
var argText;
if (isNaN(currArg)) {
argText = 'nan';
flagZeroPad = false;
} else if (!isFinite(currArg)) {
argText = (currArg < 0 ? '-' : '') + 'inf';
flagZeroPad = false;
} else {
var isGeneral = false;
var effectivePrecision = Math.min(precision, 20);
// Convert g/G to f/F or e/E, as per:
// http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html
if (next == 'g'.charCodeAt(0) || next == 'G'.charCodeAt(0)) {
isGeneral = true;
precision = precision || 1;
var exponent = parseInt(currArg.toExponential(effectivePrecision).split('e')[1], 10);
if (precision > exponent && exponent >= -4) {
next = ((next == 'g'.charCodeAt(0)) ? 'f' : 'F').charCodeAt(0);
precision -= exponent + 1;
} else {
next = ((next == 'g'.charCodeAt(0)) ? 'e' : 'E').charCodeAt(0);
precision--;
}
effectivePrecision = Math.min(precision, 20);
}
if (next == 'e'.charCodeAt(0) || next == 'E'.charCodeAt(0)) {
argText = currArg.toExponential(effectivePrecision);
// Make sure the exponent has at least 2 digits.
if (/[eE][-+]\d$/.test(argText)) {
argText = argText.slice(0, -1) + '0' + argText.slice(-1);
}
} else if (next == 'f'.charCodeAt(0) || next == 'F'.charCodeAt(0)) {
argText = currArg.toFixed(effectivePrecision);
}
var parts = argText.split('e');
if (isGeneral && !flagAlternative) {
// Discard trailing zeros and periods.
while (parts[0].length > 1 && parts[0].indexOf('.') != -1 &&
(parts[0].slice(-1) == '0' || parts[0].slice(-1) == '.')) {
parts[0] = parts[0].slice(0, -1);
}
} else {
// Make sure we have a period in alternative mode.
if (flagAlternative && argText.indexOf('.') == -1) parts[0] += '.';
// Zero pad until required precision.
while (precision > effectivePrecision++) parts[0] += '0';
}
argText = parts[0] + (parts.length > 1 ? 'e' + parts[1] : '');
// Capitalize 'E' if needed.
if (next == 'E'.charCodeAt(0)) argText = argText.toUpperCase();
// Add sign.
if (flagAlwaysSigned && currArg >= 0) {
argText = '+' + argText;
}
}
// Add padding.
while (argText.length < width) {
if (flagLeftAlign) {
argText += ' ';
} else {
if (flagZeroPad && (argText[0] == '-' || argText[0] == '+')) {
argText = argText[0] + '0' + argText.slice(1);
} else {
argText = (flagZeroPad ? '0' : ' ') + argText;
}
}
}
// Adjust case.
if (next < 'a'.charCodeAt(0)) argText = argText.toUpperCase();
// Insert the result into the buffer.
argText.split('').forEach(function(chr) {
ret.push(chr.charCodeAt(0));
});
} else if (next == 's'.charCodeAt(0)) {
// String.
var arg = getNextArg('i8*');
var copiedString;
if (arg) {
copiedString = String_copy(arg);
if (precisionSet && copiedString.length > precision) {
copiedString = copiedString.slice(0, precision);
}
} else {
copiedString = intArrayFromString('(null)', true);
}
if (!flagLeftAlign) {
while (copiedString.length < width--) {
ret.push(' '.charCodeAt(0));
}
}
ret = ret.concat(copiedString);
if (flagLeftAlign) {
while (copiedString.length < width--) {
ret.push(' '.charCodeAt(0));
}
}
} else if (next == 'c'.charCodeAt(0)) {
// Character.
if (flagLeftAlign) ret.push(getNextArg('i8'));
while (--width > 0) {
ret.push(' '.charCodeAt(0));
}
if (!flagLeftAlign) ret.push(getNextArg('i8'));
} else if (next == 'n'.charCodeAt(0)) {
// Write the length written so far to the next parameter.
var ptr = getNextArg('i32*');
HEAP32[((ptr)>>2)]=ret.length
} else if (next == '%'.charCodeAt(0)) {
// Literal percent sign.
ret.push(curr);
} else {
// Unknown specifiers remain untouched.
for (var i = startTextIndex; i < textIndex + 2; i++) {
ret.push(HEAP8[(i)]);
}
}
textIndex += 2;
// TODO: Support a/A (hex float) and m (last error) specifiers.
// TODO: Support %1${specifier} for arg selection.
} else {
ret.push(curr);
textIndex += 1;
}
}
return ret;
}function _fprintf(stream, format, varargs) {
// int fprintf(FILE *restrict stream, const char *restrict format, ...);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
var result = __formatString(format, varargs);
var stack = Runtime.stackSave();
var ret = _fwrite(allocate(result, 'i8', ALLOC_STACK), 1, result.length, stream);
Runtime.stackRestore(stack);
return ret;
}function _printf(format, varargs) {
// int printf(const char *restrict format, ...);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
var stdout = HEAP32[((_stdout)>>2)];
return _fprintf(stdout, format, varargs);
}
function _memset(ptr, value, num) {
var dest, stop, stop4, fast, value;
dest = ptr;
stop = dest + num;
value = value;
if (value < 0) value += 256;
value = value + (value<<8) + (value<<16) + (value*16777216);
while (dest%4 !== 0 && dest < stop) {
;; HEAP8[dest++] = value;
}
dest >>= 2;
stop4 = stop >> 2;
while (dest < stop4) {
;;;;;;; HEAP32[dest++] = value;
}
dest <<= 2;
while (dest < stop) {
;; HEAP8[dest++] = value;
}
}
function _malloc(bytes) {
return Runtime.staticAlloc(bytes || 1); // accept 0 as an input because libc implementations tend to
}
function _free(){}
FS.init(); __ATEXIT__.push({ func: function() { FS.quit() } });
___setErrNo(0);
// === Auto-generated postamble setup entry stuff ===
Module.callMain = function callMain(args) {
var argc = args.length+1;
function pad() {
for (var i = 0; i < 4-1; i++) {
argv.push(0);
}
}
var argv = [allocate(intArrayFromString("/bin/this.program"), 'i8', ALLOC_STATIC) ];
pad();
for (var i = 0; i < argc-1; i = i + 1) {
argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_STATIC));
pad();
}
argv.push(0);
argv = allocate(argv, 'i32', ALLOC_STATIC);
return _main(argc, argv, 0);
}
var __str;
__str=allocate([104,101,108,108,111,44,32,119,111,114,108,100,33,10,0] /* hello, world!\0A\00 */, "i8", ALLOC_STATIC);
FUNCTION_TABLE = [0,0]; Module["FUNCTION_TABLE"] = FUNCTION_TABLE;
function run(args) {
args = args || Module['arguments'];
__globalConstructor__();
var ret = null;
if (Module['_main']) {
ret = Module.callMain(args);
__shutdownRuntime__();
}
return ret;
}
Module['run'] = run;
// {{PRE_RUN_ADDITIONS}}
// In a hackish way, we disable permissions until now, so setup code works, but enable them for runtime so compile code works with permissions
try {
FS.ignorePermissions = false;
} catch(e){}
if (!Module['noInitialRun']) {
var ret = run();
}
// {{POST_RUN_ADDITIONS}}
// {{MODULE_ADDITIONS}}
// EMSCRIPTEN_GENERATED_FUNCTIONS: ["_main"]
(Emscripten: Running sanity checks)
test_emcc (__main__.other) ... ERROR
======================================================================
ERROR: test_emcc (__main__.other)
----------------------------------------------------------------------
Traceback (most recent call last):
File "tests/runner.py", line 5151, in test_emcc
self.assertContained('hello, world!', self.run_llvm_interpreter([target]))
File "tests/runner.py", line 210, in assertContained
additional_info
Exception: Expected to find 'hello, world!' in '', diff:
--- expected
+++ actual
@@ -1 +1 @@
-hello, world!
+
----------------------------------------------------------------------
Ran 1 test in 3.416s
FAILED (errors=1)
Running Emscripten tests...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment