aboutsummaryrefslogtreecommitdiff
path: root/src/library.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/library.js')
-rw-r--r--src/library.js142
1 files changed, 64 insertions, 78 deletions
diff --git a/src/library.js b/src/library.js
index 1bdd840d..5834797f 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) {
@@ -4844,14 +4849,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 +4942,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 +5013,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 +5497,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 +5570,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 +5640,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 +5667,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 +5709,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 +5744,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 +5778,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 +5797,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 +5996,8 @@ LibraryManager.library = {
return 0;
},
+ freelocale: function(locale) {},
+
uselocale: function(locale) {
return 0;
},
@@ -6453,6 +6437,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 +6472,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 +6490,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;
},