diff options
Diffstat (limited to 'src/library.js')
-rw-r--r-- | src/library.js | 147 |
1 files changed, 66 insertions, 81 deletions
diff --git a/src/library.js b/src/library.js index 1bdd840d..c01b2d70 100644 --- a/src/library.js +++ b/src/library.js @@ -20,10 +20,11 @@ LibraryManager.library = { // File system base. // ========================================================================== - stdin: 0, - stdout: 0, - stderr: 0, - _impure_ptr: 0, + // keep this low in memory, because we flatten arrays with them in them + stdin: 'allocate(1, "i32*", ALLOC_STACK)', + stdout: 'allocate(1, "i32*", ALLOC_STACK)', + stderr: 'allocate(1, "i32*", ALLOC_STACK)', + _impure_ptr: 'allocate(1, "i32*", ALLOC_STACK)', $FS__deps: ['$ERRNO_CODES', '__setErrNo', 'stdin', 'stdout', 'stderr', '_impure_ptr'], $FS__postset: '__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });' + @@ -572,10 +573,10 @@ LibraryManager.library = { eof: false, ungotten: [] }; - // Allocate these on the stack (and never free, we are called from ATINIT or earlier), to keep their locations low - _stdin = allocate([1], 'void*', ALLOC_STACK); - _stdout = allocate([2], 'void*', ALLOC_STACK); - _stderr = allocate([3], 'void*', ALLOC_STACK); + assert(Math.max(_stdin, _stdout, _stderr) < 128); // make sure these are low, we flatten arrays with these + {{{ makeSetValue('_stdin', 0, 1, 'void*') }}}; + {{{ makeSetValue('_stdout', 0, 2, 'void*') }}}; + {{{ makeSetValue('_stderr', 0, 3, 'void*') }}}; // Other system paths FS.createPath('/', 'dev/shm/tmp', true, true); // temp files @@ -591,9 +592,9 @@ LibraryManager.library = { FS.checkStreams(); assert(FS.streams.length < 1024); // at this early stage, we should not have a large set of file descriptors - just a few #endif - __impure_ptr = allocate([ allocate( + allocate([ allocate( {{{ Runtime.QUANTUM_SIZE === 4 ? '[0, 0, 0, 0, _stdin, 0, 0, 0, _stdout, 0, 0, 0, _stderr, 0, 0, 0]' : '[0, _stdin, _stdout, _stderr]' }}}, - 'void*', ALLOC_STATIC) ], 'void*', ALLOC_STATIC); + 'void*', ALLOC_STATIC) ], 'void*', ALLOC_NONE, __impure_ptr); }, quit: function() { @@ -3616,7 +3617,9 @@ LibraryManager.library = { }, bsearch: function(key, base, num, size, compar) { - var cmp = FUNCTION_TABLE[compar]; + var cmp = function(x, y) { + return Runtime.dynCall('iii', compar, [x, y]) + }; var left = 0; var right = num; var mid, test, addr; @@ -3810,7 +3813,7 @@ LibraryManager.library = { #if USE_TYPED_ARRAYS == 2 if (bits == 64) { - ret = [{{{ splitI64('ret') }}}]; + {{{ makeStructuralReturn(splitI64('ret')) }}}; } #endif @@ -3854,11 +3857,13 @@ LibraryManager.library = { }, qsort__deps: ['memcpy'], - qsort: function(base, num, size, comparator) { + qsort: function(base, num, size, cmp) { if (num == 0 || size == 0) return; // forward calls to the JavaScript sort method // first, sort the items logically - comparator = FUNCTION_TABLE[comparator]; + var comparator = function(x, y) { + return Runtime.dynCall('iii', cmp, [x, y]); + } var keys = []; for (var i = 0; i < num; i++) keys.push(i); keys.sort(function(a, b) { @@ -3874,9 +3879,10 @@ LibraryManager.library = { _free(temp); }, - environ: null, - __environ: null, - __buildEnvironment__deps: ['environ', '__environ'], + environ: 'allocate(1, "i32*", ALLOC_STACK)', + __environ__deps: ['environ'], + __environ: '_environ', + __buildEnvironment__deps: ['__environ'], __buildEnvironment: function(env) { // WARNING: Arbitrary limit! var MAX_ENV_VALUES = 64; @@ -3885,7 +3891,8 @@ LibraryManager.library = { // Statically allocate memory for the environment. var poolPtr; var envPtr; - if (_environ === null) { + if (!___buildEnvironment.called) { + ___buildEnvironment.called = true; // Set default values. Use string keys for Closure Compiler compatibility. ENV['USER'] = 'root'; ENV['PATH'] = '/'; @@ -3898,9 +3905,7 @@ LibraryManager.library = { envPtr = allocate(MAX_ENV_VALUES * {{{ Runtime.QUANTUM_SIZE }}}, 'i8*', ALLOC_STATIC); {{{ makeSetValue('envPtr', '0', 'poolPtr', 'i8*') }}} - _environ = allocate([envPtr], 'i8**', ALLOC_STATIC); - // Set up global variable alias. - ___environ = _environ; + {{{ makeSetValue('_environ', 0, 'envPtr', 'i8*') }}}; } else { envPtr = {{{ makeGetValue('_environ', '0', 'i8**') }}}; poolPtr = {{{ makeGetValue('envPtr', '0', 'i8*') }}}; @@ -4097,14 +4102,14 @@ LibraryManager.library = { memcpy__inline: function (dest, src, num, align) { var ret = ''; #if ASSERTIONS - ret += "assert(" + num + " % 1 === 0, 'memcpy given ' + " + num + " + ' bytes to copy. Problem with quantum=1 corrections perhaps?');"; + ret += "assert(" + num + " % 1 === 0);"; //, 'memcpy given ' + " + num + " + ' bytes to copy. Problem with quantum=1 corrections perhaps?');"; #endif ret += makeCopyValues(dest, src, num, 'null', null, align); return ret; }, memcpy: function (dest, src, num, align) { #if ASSERTIONS - assert(num % 1 === 0, 'memcpy given ' + num + ' bytes to copy. Problem with quantum=1 corrections perhaps?'); + assert(num % 1 === 0); //, 'memcpy given ' + num + ' bytes to copy. Problem with quantum=1 corrections perhaps?'); #endif #if USE_TYPED_ARRAYS == 2 if (num >= {{{ SEEK_OPTIMAL_ALIGN_MIN }}} && src % 2 == dest % 2) { @@ -4716,9 +4721,8 @@ LibraryManager.library = { // ========================================================================== llvm_va_start__inline: function(ptr) { - // varargs - we received a pointer to the varargs as a final 'extra' parameter - var data = 'arguments[' + Framework.currItem.funcData.ident + '.length]'; - return makeSetValue(ptr, 0, data, 'void*'); + // varargs - we received a pointer to the varargs as a final 'extra' parameter called 'varrp' + return makeSetValue(ptr, 0, 'varrp', 'void*'); }, llvm_va_end: function() {}, @@ -4844,14 +4848,18 @@ LibraryManager.library = { return; } // Clear state flag. - __THREW__ = false; +#if ASM_JS + asm.setThrew(0); +#else + __THREW__ = 0; +#endif // Clear type. {{{ makeSetValue('_llvm_eh_exception.buf', QUANTUM_SIZE, '0', 'void*') }}} // Call destructor if one is registered then clear it. var ptr = {{{ makeGetValue('_llvm_eh_exception.buf', '0', 'void*') }}}; var destructor = {{{ makeGetValue('_llvm_eh_exception.buf', 2 * QUANTUM_SIZE, 'void*') }}}; if (destructor) { - FUNCTION_TABLE[destructor](ptr); + Runtime.dynCall('vi', destructor, [ptr]); {{{ makeSetValue('_llvm_eh_exception.buf', 2 * QUANTUM_SIZE, '0', 'i32') }}} } // Free ptr if it isn't null. @@ -4933,12 +4941,12 @@ LibraryManager.library = { // return the type of the catch block which should be called. for (var i = 0; i < typeArray.length; i++) { if (___cxa_does_inherit(typeArray[i], throwntype, thrown)) - return { f0:thrown, f1:typeArray[i] }; + {{{ makeStructuralReturn(['thrown', 'typeArray[i]']) }}}; } // Shouldn't happen unless we have bogus data in typeArray // or encounter a type for which emscripten doesn't have suitable // typeinfo defined. Best-efforts match just in case. - return { f0:thrown, f1 :throwntype }; + {{{ makeStructuralReturn(['thrown', 'throwntype']) }}}; }, // Recursively walks up the base types of 'possibilityType' @@ -5004,73 +5012,51 @@ LibraryManager.library = { llvm_uadd_with_overflow_i8: function(x, y) { x = x & 0xff; y = y & 0xff; - return { - f0: (x+y) & 0xff, - f1: x+y > 255 - }; + {{{ makeStructuralReturn(['(x+y) & 0xff', 'x+y > 255']) }}}; }, llvm_umul_with_overflow_i8: function(x, y) { x = x & 0xff; y = y & 0xff; - return { - f0: (x*y) & 0xff, - f1: x*y > 255 - }; + {{{ makeStructuralReturn(['(x*y) & 0xff', 'x*y > 255']) }}}; }, llvm_uadd_with_overflow_i16: function(x, y) { x = x & 0xffff; y = y & 0xffff; - return { - f0: (x+y) & 0xffff, - f1: x+y > 65535 - }; + {{{ makeStructuralReturn(['(x+y) & 0xffff', 'x+y > 65535']) }}}; }, llvm_umul_with_overflow_i16: function(x, y) { x = x & 0xffff; y = y & 0xffff; - return { - f0: (x*y) & 0xffff, - f1: x*y > 65535 - }; + {{{ makeStructuralReturn(['(x*y) & 0xffff', 'x*y > 65535']) }}}; }, llvm_uadd_with_overflow_i32: function(x, y) { x = x>>>0; y = y>>>0; - return { - f0: (x+y)>>>0, - f1: x+y > 4294967295 - }; + {{{ makeStructuralReturn(['(x+y)>>>0', 'x+y > 4294967295']) }}}; }, llvm_umul_with_overflow_i32: function(x, y) { x = x>>>0; y = y>>>0; - return { - f0: (x*y)>>>0, - f1: x*y > 4294967295 - }; + {{{ makeStructuralReturn(['(x*y)>>>0', 'x*y > 4294967295']) }}}; }, llvm_uadd_with_overflow_i64__deps: [function() { Types.preciseI64MathUsed = 1 }], llvm_uadd_with_overflow_i64: function(xl, xh, yl, yh) { i64Math.add(xl, xh, yl, yh); - return { - f0: i64Math.result, - f1: 0 // XXX Need to hack support for this in long.js - }; + {{{ makeStructuralReturn(['HEAP32[tempDoublePtr>>2]', 'HEAP32[tempDoublePtr+4>>2]', '0']) }}}; + // XXX Need to hack support for second param in long.js }, llvm_umul_with_overflow_i64__deps: [function() { Types.preciseI64MathUsed = 1 }], llvm_umul_with_overflow_i64: function(xl, xh, yl, yh) { - i64Math.mul(xl, xh, yl, yh); - return { - f0: i64Math.result, - f1: 0 // XXX Need to hack support for this in long.js - }; + i64Math.multiply(xl, xh, yl, yh); + {{{ makeStructuralReturn(['HEAP32[tempDoublePtr>>2]', 'HEAP32[tempDoublePtr+4>>2]', '0']) }}}; + // XXX Need to hack support for second param in long.js }, llvm_stacksave: function() { @@ -5510,7 +5496,7 @@ LibraryManager.library = { } try { - var lib_module = eval(lib_data)(FUNCTION_TABLE.length); + var lib_module = eval(lib_data)({{{ Functions.getTable('x') }}}.length); } catch (e) { #if ASSERTIONS Module.printErr('Error in loading dynamic library: ' + e); @@ -5583,9 +5569,9 @@ LibraryManager.library = { } else { var result = lib.module[symbol]; if (typeof result == 'function') { - FUNCTION_TABLE.push(result); - FUNCTION_TABLE.push(0); - result = FUNCTION_TABLE.length - 2; + {{{ Functions.getTable('x') }}}.push(result); + {{{ Functions.getTable('x') }}}.push(0); + result = {{{ Functions.getTable('x') }}}.length - 2; lib.cached_functions = result; } return result; @@ -5653,11 +5639,11 @@ LibraryManager.library = { 'tm_gmtoff', 'tm_zone'], '%struct.tm'), // Statically allocated time struct. - __tm_current: 0, + __tm_current: 'allocate({{{ Runtime.QUANTUM_SIZE }}}*26, "i8", ALLOC_STACK)', // Statically allocated timezone strings. __tm_timezones: {}, // Statically allocated time strings. - __tm_formatted: 0, + __tm_formatted: 'allocate({{{ Runtime.QUANTUM_SIZE }}}*26, "i8", ALLOC_STACK)', mktime__deps: ['__tm_struct_layout', 'tzset'], mktime: function(tmPtr) { @@ -5680,7 +5666,6 @@ LibraryManager.library = { gmtime__deps: ['malloc', '__tm_struct_layout', '__tm_current', 'gmtime_r'], gmtime: function(time) { - if (!___tm_current) ___tm_current = _malloc(___tm_struct_layout.__size__); return _gmtime_r(time, ___tm_current); }, @@ -5723,7 +5708,6 @@ LibraryManager.library = { localtime__deps: ['malloc', '__tm_struct_layout', '__tm_current', 'localtime_r'], localtime: function(time) { - if (!___tm_current) ___tm_current = _malloc(___tm_struct_layout.__size__); return _localtime_r(time, ___tm_current); }, @@ -5759,7 +5743,6 @@ LibraryManager.library = { asctime__deps: ['malloc', '__tm_formatted', 'asctime_r'], asctime: function(tmPtr) { - if (!___tm_formatted) ___tm_formatted = _malloc(26); return _asctime_r(tmPtr, ___tm_formatted); }, @@ -5794,18 +5777,17 @@ LibraryManager.library = { // TODO: Initialize these to defaults on startup from system settings. // Note: glibc has one fewer underscore for all of these. Also used in other related functions (timegm) - _tzname: null, - _daylight: null, - _timezone: null, + _tzname: 'allocate({{{ 2*Runtime.QUANTUM_SIZE }}}, "i32*", ALLOC_STACK)', + _daylight: 'allocate(1, "i32*", ALLOC_STACK)', + _timezone: 'allocate(1, "i32*", ALLOC_STACK)', tzset__deps: ['_tzname', '_daylight', '_timezone'], tzset: function() { // TODO: Use (malleable) environment variables instead of system settings. - if (__tzname) return; // glibc does not need the double __ + if (_tzset.called) return; + _tzset.called = true; - __timezone = _malloc({{{ Runtime.QUANTUM_SIZE }}}); {{{ makeSetValue('__timezone', '0', '-(new Date()).getTimezoneOffset() * 60', 'i32') }}} - __daylight = _malloc({{{ Runtime.QUANTUM_SIZE }}}); var winter = new Date(2000, 0, 1); var summer = new Date(2000, 6, 1); {{{ makeSetValue('__daylight', '0', 'Number(winter.getTimezoneOffset() != summer.getTimezoneOffset())', 'i32') }}} @@ -5814,7 +5796,6 @@ LibraryManager.library = { var summerName = 'GMT'; // XXX do not rely on browser timezone info, it is very unpredictable | summer.toString().match(/\(([A-Z]+)\)/)[1]; var winterNamePtr = allocate(intArrayFromString(winterName), 'i8', ALLOC_NORMAL); var summerNamePtr = allocate(intArrayFromString(summerName), 'i8', ALLOC_NORMAL); - __tzname = _malloc(2 * {{{ Runtime.QUANTUM_SIZE }}}); // glibc does not need the double __ {{{ makeSetValue('__tzname', '0', 'winterNamePtr', 'i32') }}} {{{ makeSetValue('__tzname', Runtime.QUANTUM_SIZE, 'summerNamePtr', 'i32') }}} }, @@ -6014,6 +5995,8 @@ LibraryManager.library = { return 0; }, + freelocale: function(locale) {}, + uselocale: function(locale) { return 0; }, @@ -6453,6 +6436,8 @@ LibraryManager.library = { pthread_mutexattr_destroy: function() {}, pthread_mutex_lock: function() {}, pthread_mutex_unlock: function() {}, + pthread_cond_init: function() {}, + pthread_cond_destroy: function() {}, pthread_cond_broadcast: function() {}, pthread_self: function() { //FIXME: assumes only a single thread @@ -6486,7 +6471,7 @@ LibraryManager.library = { pthread_once: function(ptr, func) { if (!_pthread_once.seen) _pthread_once.seen = {}; if (ptr in _pthread_once.seen) return; - FUNCTION_TABLE[func](); + Runtime.dynCall('v', func); _pthread_once.seen[ptr] = 1; }, @@ -6504,7 +6489,7 @@ LibraryManager.library = { }, pthread_cleanup_push: function(routine, arg) { - __ATEXIT__.push({ func: function() { FUNCTION_TABLE[routine](arg) } }) + __ATEXIT__.push({ func: function() { Runtime.dynCall('vi', routine, [arg]) } }) _pthread_cleanup_push.level = __ATEXIT__.length; }, |