diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/intertyper.js | 3 | ||||
-rw-r--r-- | src/jsifier.js | 40 | ||||
-rw-r--r-- | src/library.js | 184 | ||||
-rw-r--r-- | src/library_browser.js | 72 | ||||
-rw-r--r-- | src/library_egl.js | 76 | ||||
-rw-r--r-- | src/library_fs.js | 44 | ||||
-rw-r--r-- | src/library_gl.js | 360 | ||||
-rw-r--r-- | src/library_glut.js | 11 | ||||
-rw-r--r-- | src/library_idbfs.js | 26 | ||||
-rw-r--r-- | src/library_memfs.js | 6 | ||||
-rw-r--r-- | src/library_openal.js | 8 | ||||
-rw-r--r-- | src/library_sdl.js | 254 | ||||
-rw-r--r-- | src/library_sockfs.js | 10 | ||||
-rw-r--r-- | src/modules.js | 48 | ||||
-rw-r--r-- | src/parseTools.js | 115 | ||||
-rw-r--r-- | src/preamble.js | 48 | ||||
-rw-r--r-- | src/proxyClient.js | 2 | ||||
-rw-r--r-- | src/proxyWorker.js | 20 | ||||
-rw-r--r-- | src/runtime.js | 8 | ||||
-rw-r--r-- | src/settings.js | 26 | ||||
-rw-r--r-- | src/shell.js | 22 | ||||
-rw-r--r-- | src/struct_info.json | 21 | ||||
-rw-r--r-- | src/utility.js | 9 |
23 files changed, 996 insertions, 417 deletions
diff --git a/src/intertyper.js b/src/intertyper.js index fceeb38d..fa53c652 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -680,6 +680,9 @@ function intertyper(lines, sidePass, baseLineNums) { args.push(ident); }); } + item.ident = expandLLVMString(item.ident).replace(/(#[^\n]*)/g, function(m) { + return '/* ' + m.substr(1) + ' */'; // fix asm comments to js comments + }); if (item.assignTo) item.ident = 'return ' + item.ident; item.ident = '(function(' + params + ') { ' + item.ident + ' })(' + args + ');'; return { ret: item, item: item }; diff --git a/src/jsifier.js b/src/jsifier.js index 0da48a8c..22a230ca 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -490,10 +490,15 @@ function JSify(data, functionsOnly, givenFunctions) { } else { // If this is not linkable, anything not in the library is definitely missing var cancel = false; + if (item.ident in DEAD_FUNCTIONS) { + LibraryManager.library[shortident] = new Function("Module['printErr']('dead function: " + shortident + "'); abort(-1);"); + delete LibraryManager.library[shortident + '__inline']; + delete LibraryManager.library[shortident + '__deps']; + } if (!LINKABLE && !LibraryManager.library.hasOwnProperty(shortident) && !LibraryManager.library.hasOwnProperty(shortident + '__inline')) { if (ERROR_ON_UNDEFINED_SYMBOLS) error('unresolved symbol: ' + shortident); - if (VERBOSE || WARN_ON_UNDEFINED_SYMBOLS) printErr('warning: unresolved symbol: ' + shortident); - if (ASM_JS || item.ident in DEAD_FUNCTIONS) { + else if (VERBOSE || WARN_ON_UNDEFINED_SYMBOLS) warn('unresolved symbol: ' + shortident); + if (ASM_JS) { // emit a stub that will fail during runtime. this allows asm validation to succeed. LibraryManager.library[shortident] = new Function("Module['printErr']('missing function: " + shortident + "'); abort(-1);"); } else { @@ -756,14 +761,7 @@ function JSify(data, functionsOnly, givenFunctions) { if (func.setjmpTable && !ASM_JS) { ret += ' } catch(e) { if (!e.longjmp || !(e.id in mySetjmpIds)) throw(e); setjmpTable[setjmpLabels[e.id]](e.value) }'; } - if (ASM_JS && func.returnType !== 'void') { - // Add a return - if (func.returnType in Runtime.FLOAT_TYPES) { - ret += ' return +0;\n'; - } else { - ret += ' return 0;\n'; - } - } + if (ASM_JS && func.returnType !== 'void') ret += ' return ' + asmInitializer(func.returnType) + ';\n'; // Add a return } else { ret += (SHOW_LABELS ? indent + '/* ' + block.entries[0] + ' */' : '') + '\n' + getLabelLines(block.labels[0]); } @@ -833,11 +831,7 @@ function JSify(data, functionsOnly, givenFunctions) { var lastReturn = func.JS.lastIndexOf('return '); if ((lastCurly < 0 && lastReturn < 0) || // no control flow, no return (lastCurly >= 0 && lastReturn < lastCurly)) { // control flow, no return past last join - if (func.returnType in Runtime.FLOAT_TYPES) { - func.JS += ' return +0;\n'; - } else { - func.JS += ' return 0;\n'; - } + func.JS += ' return ' + asmInitializer(func.returnType) + ';\n'; } } func.JS += '}\n'; @@ -1337,7 +1331,7 @@ function JSify(data, functionsOnly, givenFunctions) { if (isNumber(item.ident)) { // Direct read from a memory address; this may be an intentional segfault, if not, it is a bug in the source if (ASM_JS) { - return asmCoercion('abort(' + item.ident + ')', item.type); + return asmFFICoercion('abort(' + item.ident + ')', item.type); } else { item.assignTo = null; return 'throw "fault on read from ' + item.ident + '";'; @@ -1514,8 +1508,10 @@ function JSify(data, functionsOnly, givenFunctions) { args = args.map(function(arg, i) { return indexizeFunctions(arg, argsTypes[i]) }); if (ASM_JS) { - if (shortident in Functions.libraryFunctions || simpleIdent in Functions.libraryFunctions || byPointerForced || invoke || extCall || funcData.setjmpTable) { - args = args.map(function(arg, i) { return asmCoercion(arg, argsTypes[i]) }); + var ffiCall = (shortident in Functions.libraryFunctions || simpleIdent in Functions.libraryFunctions || byPointerForced || invoke || extCall || funcData.setjmpTable) && + !(simpleIdent in JS_MATH_BUILTINS); + if (ffiCall) { + args = args.map(function(arg, i) { return asmCoercion(arg, ensureValidFFIType(argsTypes[i])) }); } else { args = args.map(function(arg, i) { return asmEnsureFloat(arg, argsTypes[i]) }); } @@ -1592,7 +1588,7 @@ function JSify(data, functionsOnly, givenFunctions) { returnType = getReturnType(type); if (callIdent in Functions.implementedFunctions) { // LLVM sometimes bitcasts for no reason. We must call using the exact same type as the actual function is generated as - var trueType = Functions.getSignatureReturnType(Functions.implementedFunctions[callIdent]); + var trueType = Functions.getSignatureType(Functions.implementedFunctions[callIdent][0]); if (trueType !== returnType && !isIdenticallyImplemented(trueType, returnType)) { if (VERBOSE) warnOnce('Fixing function call based on return type from signature, on ' + [callIdent, returnType, trueType]); returnType = trueType; @@ -1628,7 +1624,11 @@ function JSify(data, functionsOnly, givenFunctions) { var ret = callIdent + '(' + args.join(',') + ')'; if (ASM_JS) { // TODO: do only when needed (library functions and Math.*?) XXX && simpleIdent in Functions.libraryFunctions) { - ret = asmCoercion(ret, returnType); + if (ffiCall) { + ret = asmFFICoercion(ret, returnType); + } else { + ret = asmCoercion(ret, returnType); + } if (simpleIdent == 'abort' && funcData.returnType != 'void') { ret += '; return ' + asmCoercion('0', funcData.returnType); // special case: abort() can happen without return, breaking the return type of asm functions. ensure a return } diff --git a/src/library.js b/src/library.js index e3cdc7c3..48acf6ac 100644 --- a/src/library.js +++ b/src/library.js @@ -847,10 +847,7 @@ LibraryManager.library = { ___setErrNo(ERRNO_CODES.ERANGE); return 0; } else { - for (var i = 0; i < cwd.length; i++) { - {{{ makeSetValue('buf', 'i', 'cwd.charCodeAt(i)', 'i8') }}} - } - {{{ makeSetValue('buf', 'i', '0', 'i8') }}} + writeAsciiToMemory(cwd, buf); return buf; } }, @@ -1193,7 +1190,6 @@ LibraryManager.library = { _exit: function(status) { // void _exit(int status); // http://pubs.opengroup.org/onlinepubs/000095399/functions/exit.html - Module.print('exit(' + status + ') called'); Module['exit'](status); }, fork__deps: ['__setErrNo', '$ERRNO_CODES'], @@ -1293,10 +1289,7 @@ LibraryManager.library = { if (namesize < ret.length + 1) { return ___setErrNo(ERRNO_CODES.ERANGE); } else { - for (var i = 0; i < ret.length; i++) { - {{{ makeSetValue('name', 'i', 'ret.charCodeAt(i)', 'i8') }}} - } - {{{ makeSetValue('name', 'i', '0', 'i8') }}} + writeAsciiToMemory(ret, name); return 0; } }, @@ -1602,12 +1595,12 @@ LibraryManager.library = { if (format.indexOf('%n') >= 0) { // need to track soFar var _get = get; - get = function() { + get = function get() { soFar++; return _get(); } var _unget = unget; - unget = function() { + unget = function unget() { soFar--; return _unget(); } @@ -2699,10 +2692,7 @@ LibraryManager.library = { var result = dir + '/' + name; if (!_tmpnam.buffer) _tmpnam.buffer = _malloc(256); if (!s) s = _tmpnam.buffer; - for (var i = 0; i < result.length; i++) { - {{{ makeSetValue('s', 'i', 'result.charCodeAt(i)', 'i8') }}}; - } - {{{ makeSetValue('s', 'i', '0', 'i8') }}}; + writeAsciiToMemory(result, s); return s; }, tempnam__deps: ['tmpnam'], @@ -2755,12 +2745,12 @@ LibraryManager.library = { return -1; } var buffer = []; - var get = function() { + function get() { var c = _fgetc(stream); buffer.push(c); return c; }; - var unget = function() { + function unget() { _ungetc(buffer.pop(), stream); }; return __scanString(format, get, unget, varargs); @@ -2777,8 +2767,8 @@ LibraryManager.library = { // int sscanf(const char *restrict s, const char *restrict format, ... ); // http://pubs.opengroup.org/onlinepubs/000095399/functions/scanf.html var index = 0; - var get = function() { return {{{ makeGetValue('s', 'index++', 'i8') }}}; }; - var unget = function() { index--; }; + function get() { return {{{ makeGetValue('s', 'index++', 'i8') }}}; }; + function unget() { index--; }; return __scanString(format, get, unget, varargs); }, snprintf__deps: ['_formatString'], @@ -3040,7 +3030,7 @@ LibraryManager.library = { }, bsearch: function(key, base, num, size, compar) { - var cmp = function(x, y) { + function cmp(x, y) { #if ASM_JS return Module['dynCall_iii'](compar, x, y); #else @@ -3343,10 +3333,7 @@ LibraryManager.library = { var ptrSize = {{{ Runtime.getNativeTypeSize('i8*') }}}; for (var i = 0; i < strings.length; i++) { var line = strings[i]; - for (var j = 0; j < line.length; j++) { - {{{ makeSetValue('poolPtr', 'j', 'line.charCodeAt(j)', 'i8') }}}; - } - {{{ makeSetValue('poolPtr', 'j', '0', 'i8') }}}; + writeAsciiToMemory(line, poolPtr); {{{ makeSetValue('envPtr', 'i * ptrSize', 'poolPtr', 'i8*') }}}; poolPtr += line.length + 1; } @@ -3976,10 +3963,7 @@ LibraryManager.library = { return ___setErrNo(ERRNO_CODES.ERANGE); } else { var msg = ERRNO_MESSAGES[errnum]; - for (var i = 0; i < msg.length; i++) { - {{{ makeSetValue('strerrbuf', 'i', 'msg.charCodeAt(i)', 'i8') }}} - } - {{{ makeSetValue('strerrbuf', 'i', 0, 'i8') }}} + writeAsciiToMemory(msg, strerrbuf); return 0; } } else { @@ -4164,6 +4148,11 @@ LibraryManager.library = { }, // ========================================================================== + // GCC/LLVM specifics + // ========================================================================== + __builtin_prefetch: function(){}, + + // ========================================================================== // LLVM specifics // ========================================================================== @@ -5062,10 +5051,7 @@ LibraryManager.library = { var layout = {{{ JSON.stringify(C_STRUCTS.utsname) }}}; function copyString(element, value) { var offset = layout[element]; - for (var i = 0; i < value.length; i++) { - {{{ makeSetValue('name', 'offset + i', 'value.charCodeAt(i)', 'i8') }}} - } - {{{ makeSetValue('name', 'offset + i', '0', 'i8') }}} + writeAsciiToMemory(value, name + offset); } if (name === 0) { return -1; @@ -5108,7 +5094,7 @@ LibraryManager.library = { table[from + i] = {}; sigs.forEach(function(sig) { // TODO: new Function etc. var full = 'dynCall_' + sig; - table[from + i][sig] = function() { + table[from + i][sig] = function dynCall_sig() { arguments[0] -= from; return asm[full].apply(null, arguments); } @@ -5132,7 +5118,7 @@ LibraryManager.library = { // patch js module dynCall_* to use functionTable sigs.forEach(function(sig) { - jsModule['dynCall_' + sig] = function() { + jsModule['dynCall_' + sig] = function dynCall_sig() { return table[arguments[0]][sig].apply(null, arguments); }; }); @@ -5295,6 +5281,16 @@ LibraryManager.library = { } }, + dladdr: function(addr, info) { + // report all function pointers as coming from this program itself XXX not really correct in any way + var fname = allocate(intArrayFromString("/bin/this.program"), 'i8', ALLOC_NORMAL); // XXX leak + {{{ makeSetValue('addr', 0, 'fname', 'i32') }}}; + {{{ makeSetValue('addr', QUANTUM_SIZE, '0', 'i32') }}}; + {{{ makeSetValue('addr', QUANTUM_SIZE*2, '0', 'i32') }}}; + {{{ makeSetValue('addr', QUANTUM_SIZE*3, '0', 'i32') }}}; + return 1; + }, + // ========================================================================== // pwd.h // ========================================================================== @@ -5596,7 +5592,7 @@ LibraryManager.library = { var WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; var MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; - var leadingSomething = function(value, digits, character) { + function leadingSomething(value, digits, character) { var str = typeof value === 'number' ? value.toString() : (value || ''); while (str.length < digits) { str = character[0]+str; @@ -5604,12 +5600,12 @@ LibraryManager.library = { return str; }; - var leadingNulls = function(value, digits) { + function leadingNulls(value, digits) { return leadingSomething(value, digits, '0'); }; - var compareByDay = function(date1, date2) { - var sgn = function(value) { + function compareByDay(date1, date2) { + function sgn(value) { return value < 0 ? -1 : (value > 0 ? 1 : 0); }; @@ -5622,7 +5618,7 @@ LibraryManager.library = { return compare; }; - var getFirstWeekStartDate = function(janFourth) { + function getFirstWeekStartDate(janFourth) { switch (janFourth.getDay()) { case 0: // Sunday return new Date(janFourth.getFullYear()-1, 11, 29); @@ -5641,7 +5637,7 @@ LibraryManager.library = { } }; - var getWeekBasedYear = function(date) { + function getWeekBasedYear(date) { var thisDate = __addDays(new Date(date.tm_year+1900, 0, 1), date.tm_yday); var janFourthThisYear = new Date(thisDate.getFullYear(), 0, 4); @@ -5928,8 +5924,8 @@ LibraryManager.library = { var matches = new RegExp('^'+pattern).exec(Pointer_stringify(buf)) // Module['print'](Pointer_stringify(buf)+ ' is matched by '+((new RegExp('^'+pattern)).source)+' into: '+JSON.stringify(matches)); - var initDate = function() { - var fixup = function(value, min, max) { + function initDate() { + function fixup(value, min, max) { return (typeof value !== 'number' || isNaN(value)) ? min : (value>=min ? (value<=max ? value: max): min); }; return { @@ -5946,7 +5942,7 @@ LibraryManager.library = { var date = initDate(); var value; - var getMatch = function(symbol) { + function getMatch(symbol) { var pos = capture.indexOf(symbol); // check if symbol appears in regexp if (pos >= 0) { @@ -6116,8 +6112,10 @@ LibraryManager.library = { // int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); var seconds = {{{ makeGetValue('rqtp', C_STRUCTS.timespec.tv_sec, 'i32') }}}; var nanoseconds = {{{ makeGetValue('rqtp', C_STRUCTS.timespec.tv_nsec, 'i32') }}}; - {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_sec, '0', 'i32') }}} - {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_nsec, '0', 'i32') }}} + if (rmtp !== 0) { + {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_sec, '0', 'i32') }}} + {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_nsec, '0', 'i32') }}} + } return _usleep((seconds * 1e6) + (nanoseconds / 1000)); }, // TODO: Implement these for real. @@ -6557,10 +6555,7 @@ LibraryManager.library = { var me = _nl_langinfo; if (!me.ret) me.ret = _malloc(32); - for (var i = 0; i < result.length; i++) { - {{{ makeSetValue('me.ret', 'i', 'result.charCodeAt(i)', 'i8') }}} - } - {{{ makeSetValue('me.ret', 'i', '0', 'i8') }}} + writeAsciiToMemory(result, me.ret); return me.ret; }, @@ -6876,6 +6871,10 @@ LibraryManager.library = { pthread_mutex_trylock: function() { return 0; }, + pthread_mutexattr_setpshared: function(attr, pshared) { + // XXX implement if/when getpshared is required + return 0; + }, pthread_cond_init: function() {}, pthread_cond_destroy: function() {}, pthread_cond_broadcast: function() { @@ -6971,6 +6970,10 @@ LibraryManager.library = { _pthread_cleanup_push.level = __ATEXIT__.length; }, + pthread_rwlock_init: function() { + return 0; // XXX + }, + // ========================================================================== // malloc.h // ========================================================================== @@ -7312,6 +7315,7 @@ LibraryManager.library = { // we're generating fake IP addresses with lookup_name that we can // resolve later on with lookup_addr. // We do the aliasing in 172.29.*.*, giving us 65536 possibilities. + $DNS__deps: ['_inet_pton4_raw', '_inet_pton6_raw'], $DNS: { address_map: { id: 1, @@ -7319,7 +7323,6 @@ LibraryManager.library = { names: {} }, - lookup_name__deps: ['_inet_pton4_raw', '_inet_pton6_raw'], lookup_name: function (name) { // If the name is already a valid ipv4 / ipv6 address, don't generate a fake one. var res = __inet_pton4_raw(name); @@ -7410,6 +7413,9 @@ LibraryManager.library = { getaddrinfo__deps: ['$Sockets', '$DNS', '_inet_pton4_raw', '_inet_ntop4_raw', '_inet_pton6_raw', '_inet_ntop6_raw', '_write_sockaddr', 'htonl'], getaddrinfo: function(node, service, hint, out) { + // Note getaddrinfo currently only returns a single addrinfo with ai_next defaulting to NULL. When NULL + // hints are specified or ai_family set to AF_UNSPEC or ai_socktype or ai_protocol set to 0 then we + // really should provide a linked list of suitable addrinfo values. var addrs = []; var canon = null; var addr = 0; @@ -7464,6 +7470,15 @@ LibraryManager.library = { type = proto === {{{ cDefine('IPPROTO_UDP') }}} ? {{{ cDefine('SOCK_DGRAM') }}} : {{{ cDefine('SOCK_STREAM') }}}; } + // If type or proto are set to zero in hints we should really be returning multiple addrinfo values, but for + // now default to a TCP STREAM socket so we can at least return a sensible addrinfo given NULL hints. + if (proto === 0) { + proto = {{{ cDefine('IPPROTO_TCP') }}}; + } + if (type === 0) { + type = {{{ cDefine('SOCK_STREAM') }}}; + } + if (!node && !service) { return {{{ cDefine('EAI_NONAME') }}}; } @@ -7471,14 +7486,14 @@ LibraryManager.library = { {{{ cDefine('AI_NUMERICSERV') }}}|{{{ cDefine('AI_V4MAPPED') }}}|{{{ cDefine('AI_ALL') }}}|{{{ cDefine('AI_ADDRCONFIG') }}})) { return {{{ cDefine('EAI_BADFLAGS') }}}; } - if (({{{ makeGetValue('hint', C_STRUCTS.addrinfo.ai_flags, 'i32') }}} & {{{ cDefine('AI_CANONNAME') }}}) && !node) { + if (hint !== 0 && ({{{ makeGetValue('hint', C_STRUCTS.addrinfo.ai_flags, 'i32') }}} & {{{ cDefine('AI_CANONNAME') }}}) && !node) { return {{{ cDefine('EAI_BADFLAGS') }}}; } if (flags & {{{ cDefine('AI_ADDRCONFIG') }}}) { // TODO return {{{ cDefine('EAI_NONAME') }}}; } - if (type !== {{{ cDefine('SOCK_STREAM') }}} && type !== {{{ cDefine('SOCK_DGRAM') }}}) { + if (type !== 0 && type !== {{{ cDefine('SOCK_STREAM') }}} && type !== {{{ cDefine('SOCK_DGRAM') }}}) { return {{{ cDefine('EAI_SOCKTYPE') }}}; } if (family !== {{{ cDefine('AF_UNSPEC') }}} && family !== {{{ cDefine('AF_INET') }}} && family !== {{{ cDefine('AF_INET6') }}}) { @@ -7608,12 +7623,43 @@ LibraryManager.library = { return 0; }, + // Can't use a literal for $GAI_ERRNO_MESSAGES as was done for $ERRNO_MESSAGES as the keys (e.g. EAI_BADFLAGS) + // are actually negative numbers and you can't have expressions as keys in JavaScript literals. + $GAI_ERRNO_MESSAGES: {}, + gai_strerror__deps: ['$GAI_ERRNO_MESSAGES'], gai_strerror: function(val) { - if (!_gai_strerror.error) { - _gai_strerror.error = allocate(intArrayFromString("unknown error"), 'i8', ALLOC_NORMAL); + var buflen = 256; + + // On first call to gai_strerror we initialise the buffer and populate the error messages. + if (!_gai_strerror.buffer) { + _gai_strerror.buffer = _malloc(buflen); + + GAI_ERRNO_MESSAGES['0'] = 'Success'; + GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_BADFLAGS') }}}] = 'Invalid value for \'ai_flags\' field'; + GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_NONAME') }}}] = 'NAME or SERVICE is unknown'; + GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_AGAIN') }}}] = 'Temporary failure in name resolution'; + GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_FAIL') }}}] = 'Non-recoverable failure in name res'; + GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_FAMILY') }}}] = '\'ai_family\' not supported'; + GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_SOCKTYPE') }}}] = '\'ai_socktype\' not supported'; + GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_SERVICE') }}}] = 'SERVICE not supported for \'ai_socktype\''; + GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_MEMORY') }}}] = 'Memory allocation failure'; + GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_SYSTEM') }}}] = 'System error returned in \'errno\''; + GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_OVERFLOW') }}}] = 'Argument buffer overflow'; + } + + var msg = 'Unknown error'; + + if (val in GAI_ERRNO_MESSAGES) { + if (GAI_ERRNO_MESSAGES[val].length > buflen - 1) { + msg = 'Message too long'; // EMSGSIZE message. This should never occur given the GAI_ERRNO_MESSAGES above. + } else { + msg = GAI_ERRNO_MESSAGES[val]; + } } - return _gai_strerror.error; + + writeAsciiToMemory(msg, _gai_strerror.buffer); + return _gai_strerror.buffer; }, // ========================================================================== @@ -7681,7 +7727,7 @@ LibraryManager.library = { var session = Module['webrtc']['session']; var peer = new Peer(broker); var listenOptions = Module['webrtc']['hostOptions'] || {}; - peer.onconnection = function(connection) { + peer.onconnection = function peer_onconnection(connection) { console.log('connected'); var addr; /* If this peer is connecting to the host, assign 10.0.0.1 to the host so it can be @@ -7695,7 +7741,7 @@ LibraryManager.library = { } connection['addr'] = addr; Sockets.connections[addr] = connection; - connection.ondisconnect = function() { + connection.ondisconnect = function connection_ondisconnect() { console.log('disconnect'); // Don't return the host address (10.0.0.1) to the pool if (!(session && session === Sockets.connections[addr]['route'])) { @@ -7707,12 +7753,12 @@ LibraryManager.library = { Module['webrtc']['ondisconnect'](peer); } }; - connection.onerror = function(error) { + connection.onerror = function connection_onerror(error) { if (Module['webrtc']['onerror'] && 'function' === typeof Module['webrtc']['onerror']) { Module['webrtc']['onerror'](error); } }; - connection.onmessage = function(label, message) { + connection.onmessage = function connection_onmessage(label, message) { if ('unreliable' === label) { handleMessage(addr, message.data); } @@ -7722,13 +7768,13 @@ LibraryManager.library = { Module['webrtc']['onconnect'](peer); } }; - peer.onpending = function(pending) { + peer.onpending = function peer_onpending(pending) { console.log('pending from: ', pending['route'], '; initiated by: ', (pending['incoming']) ? 'remote' : 'local'); }; - peer.onerror = function(error) { + peer.onerror = function peer_onerror(error) { console.error(error); }; - peer.onroute = function(route) { + peer.onroute = function peer_onroute(route) { if (Module['webrtc']['onpeer'] && 'function' === typeof Module['webrtc']['onpeer']) { Module['webrtc']['onpeer'](peer, route); } @@ -7744,7 +7790,7 @@ LibraryManager.library = { console.log("unable to deliver message: ", addr, header[1], message); } } - window.onbeforeunload = function() { + window.onbeforeunload = function window_onbeforeunload() { var ids = Object.keys(Sockets.connections); ids.forEach(function(id) { Sockets.connections[id].close(); @@ -7813,7 +7859,7 @@ LibraryManager.library = { } info.addr = Sockets.localAddr; // 10.0.0.254 info.host = __inet_ntop4_raw(info.addr); - info.close = function() { + info.close = function info_close() { Sockets.portmap[info.port] = undefined; } Sockets.portmap[info.port] = info; @@ -8545,7 +8591,13 @@ LibraryManager.library = { return -1; } var arg = {{{ makeGetValue('varargs', '0', 'i32') }}}; - return FS.ioctl(stream, request, arg); + + try { + return FS.ioctl(stream, request, arg); + } catch (e) { + FS.handleFSError(e); + return -1; + } }, #endif @@ -8724,6 +8776,6 @@ function autoAddDeps(object, name) { // Add aborting stubs for various libc stuff needed by libc++ ['pthread_cond_signal', 'pthread_equal', 'wcstol', 'wcstoll', 'wcstoul', 'wcstoull', 'wcstof', 'wcstod', 'wcstold', 'pthread_join', 'pthread_detach', 'catgets', 'catopen', 'catclose', 'fputwc', '__lockfile', '__unlockfile'].forEach(function(aborter) { - LibraryManager.library[aborter] = function() { throw 'TODO: ' + aborter }; + LibraryManager.library[aborter] = function aborting_stub() { throw 'TODO: ' + aborter }; }); diff --git a/src/library_browser.js b/src/library_browser.js index 59d2945e..39a1c55d 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -4,12 +4,12 @@ mergeInto(LibraryManager.library, { $Browser__deps: ['$PATH'], - $Browser__postset: 'Module["requestFullScreen"] = function(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) };\n' + // exports - 'Module["requestAnimationFrame"] = function(func) { Browser.requestAnimationFrame(func) };\n' + - 'Module["setCanvasSize"] = function(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };\n' + - 'Module["pauseMainLoop"] = function() { Browser.mainLoop.pause() };\n' + - 'Module["resumeMainLoop"] = function() { Browser.mainLoop.resume() };\n' + - 'Module["getUserMedia"] = function() { Browser.getUserMedia() }', + $Browser__postset: 'Module["requestFullScreen"] = function Module_requestFullScreen(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) };\n' + // exports + 'Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) };\n' + + 'Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };\n' + + 'Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() };\n' + + 'Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() };\n' + + 'Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() }', $Browser: { mainLoop: { scheduler: null, @@ -77,10 +77,10 @@ mergeInto(LibraryManager.library, { // might create some side data structure for use later (like an Image element, etc.). var imagePlugin = {}; - imagePlugin['canHandle'] = function(name) { + imagePlugin['canHandle'] = function imagePlugin_canHandle(name) { return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name); }; - imagePlugin['handle'] = function(byteArray, name, onload, onerror) { + imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) { var b = null; if (Browser.hasBlobConstructor) { try { @@ -103,7 +103,7 @@ mergeInto(LibraryManager.library, { assert(typeof url == 'string', 'createObjectURL must return a url as a string'); #endif var img = new Image(); - img.onload = function() { + img.onload = function img_onload() { assert(img.complete, 'Image ' + name + ' could not be decoded'); var canvas = document.createElement('canvas'); canvas.width = img.width; @@ -114,7 +114,7 @@ mergeInto(LibraryManager.library, { Browser.URLObject.revokeObjectURL(url); if (onload) onload(byteArray); }; - img.onerror = function(event) { + img.onerror = function img_onerror(event) { console.log('Image ' + url + ' could not be decoded'); if (onerror) onerror(); }; @@ -123,10 +123,10 @@ mergeInto(LibraryManager.library, { Module['preloadPlugins'].push(imagePlugin); var audioPlugin = {}; - audioPlugin['canHandle'] = function(name) { + audioPlugin['canHandle'] = function audioPlugin_canHandle(name) { return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 }; }; - audioPlugin['handle'] = function(byteArray, name, onload, onerror) { + audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) { var done = false; function finish(audio) { if (done) return; @@ -152,7 +152,7 @@ mergeInto(LibraryManager.library, { #endif var audio = new Audio(); audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926 - audio.onerror = function(event) { + audio.onerror = function audio_onerror(event) { if (done) return; console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach'); function encode64(data) { @@ -268,7 +268,7 @@ mergeInto(LibraryManager.library, { (function(prop) { switch (typeof tempCtx[prop]) { case 'function': { - wrapper[prop] = function() { + wrapper[prop] = function gl_wrapper() { if (GL.debug) { var printArgs = Array.prototype.slice.call(arguments).map(Runtime.prettyPrint); Module.printErr('[gl_f:' + prop + ':' + printArgs + ']'); @@ -359,16 +359,20 @@ mergeInto(LibraryManager.library, { canvas.requestFullScreen(); }, - requestAnimationFrame: function(func) { - if (!window.requestAnimationFrame) { - window.requestAnimationFrame = window['requestAnimationFrame'] || - window['mozRequestAnimationFrame'] || - window['webkitRequestAnimationFrame'] || - window['msRequestAnimationFrame'] || - window['oRequestAnimationFrame'] || - window['setTimeout']; + requestAnimationFrame: function requestAnimationFrame(func) { + if (typeof window === 'undefined') { // Provide fallback to setTimeout if window is undefined (e.g. in Node.js) + setTimeout(func, 1000/60); + } else { + if (!window.requestAnimationFrame) { + window.requestAnimationFrame = window['requestAnimationFrame'] || + window['mozRequestAnimationFrame'] || + window['webkitRequestAnimationFrame'] || + window['msRequestAnimationFrame'] || + window['oRequestAnimationFrame'] || + window['setTimeout']; + } + window.requestAnimationFrame(func); } - window.requestAnimationFrame(func); }, // generic abort-aware wrapper for an async callback @@ -497,7 +501,7 @@ mergeInto(LibraryManager.library, { |