aboutsummaryrefslogtreecommitdiff
path: root/src/library.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/library.js')
-rw-r--r--src/library.js83
1 files changed, 47 insertions, 36 deletions
diff --git a/src/library.js b/src/library.js
index dc0dcdd2..cfe83c6e 100644
--- a/src/library.js
+++ b/src/library.js
@@ -15,16 +15,18 @@
// object. For convenience, the short name appears here. Note that if you add a
// new function with an '_', it will not be found.
+// Memory allocated during startup, in postsets, should only be ALLOC_STATIC
+
LibraryManager.library = {
// ==========================================================================
// File system base.
// ==========================================================================
// 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)',
+ stdin: 'allocate(1, "i32*", ALLOC_STATIC)',
+ stdout: 'allocate(1, "i32*", ALLOC_STATIC)',
+ stderr: 'allocate(1, "i32*", ALLOC_STATIC)',
+ _impure_ptr: 'allocate(1, "i32*", ALLOC_STATIC)',
$FS__deps: ['$ERRNO_CODES', '__setErrNo', 'stdin', 'stdout', 'stderr', '_impure_ptr'],
$FS__postset: '__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });' +
@@ -573,7 +575,7 @@ LibraryManager.library = {
eof: false,
ungotten: []
};
- assert(Math.max(_stdin, _stdout, _stderr) < 1024); // make sure these are low, we flatten arrays with these
+ // TODO: put these low in memory like we used to assert on: assert(Math.max(_stdin, _stdout, _stderr) < 15000); // make sure these are low, we flatten arrays with these
{{{ makeSetValue(makeGlobalUse('_stdin'), 0, 1, 'void*') }}};
{{{ makeSetValue(makeGlobalUse('_stdout'), 0, 2, 'void*') }}};
{{{ makeSetValue(makeGlobalUse('_stderr'), 0, 3, 'void*') }}};
@@ -590,11 +592,11 @@ LibraryManager.library = {
FS.streams[_stderr] = FS.streams[3];
#if ASSERTIONS
FS.checkStreams();
- assert(FS.streams.length < 1024); // at this early stage, we should not have a large set of file descriptors - just a few
+ // see previous TODO on stdin etc.: assert(FS.streams.length < 1024); // at this early stage, we should not have a large set of file descriptors - just a few
#endif
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_NONE, {{{ makeGlobalUse('__impure_ptr') }}});
+ 'void*', ALLOC_DYNAMIC) ], 'void*', ALLOC_NONE, {{{ makeGlobalUse('__impure_ptr') }}});
},
quit: function() {
@@ -2425,22 +2427,17 @@ LibraryManager.library = {
// Implement a Linux-like 'memory area' for our 'process'.
// Changes the size of the memory area by |bytes|; returns the
// address of the previous top ('break') of the memory area
-
- // We need to make sure no one else allocates unfreeable memory!
- // We must control this entirely. So we don't even need to do
- // unfreeable allocations - the HEAP is ours, from STATICTOP up.
- // TODO: We could in theory slice off the top of the HEAP when
- // sbrk gets a negative increment in |bytes|...
+ // We control the "dynamic" memory - DYNAMIC_BASE to DYNAMICTOP
var self = _sbrk;
if (!self.called) {
- STATICTOP = alignMemoryPage(STATICTOP); // make sure we start out aligned
+ DYNAMICTOP = alignMemoryPage(DYNAMICTOP); // make sure we start out aligned
self.called = true;
-#if GC_SUPPORT
- _sbrk.DYNAMIC_START = STATICTOP;
-#endif
+ assert(Runtime.dynamicAlloc);
+ self.alloc = Runtime.dynamicAlloc;
+ Runtime.dynamicAlloc = function() { abort('cannot dynamically allocate, sbrk now has control') };
}
- var ret = STATICTOP;
- if (bytes != 0) Runtime.staticAlloc(bytes);
+ var ret = DYNAMICTOP;
+ if (bytes != 0) self.alloc(bytes);
return ret; // Previous break location.
},
open64: 'open',
@@ -3007,16 +3004,20 @@ LibraryManager.library = {
}
case 's': {
// String.
- var arg = getNextArg('i8*') || nullString;
- var argLength = _strlen(arg);
+ var arg = getNextArg('i8*');
+ var argLength = arg ? _strlen(arg) : '(null)'.length;
if (precisionSet) argLength = Math.min(argLength, precision);
if (!flagLeftAlign) {
while (argLength < width--) {
ret.push({{{ charCode(' ') }}});
}
}
- for (var i = 0; i < argLength; i++) {
- ret.push({{{ makeGetValue('arg++', 0, 'i8', null, true) }}});
+ if (arg) {
+ for (var i = 0; i < argLength; i++) {
+ ret.push({{{ makeGetValue('arg++', 0, 'i8', null, true) }}});
+ }
+ } else {
+ ret = ret.concat(intArrayFromString('(null)'.substr(0, argLength), true));
}
if (flagLeftAlign) {
while (argLength < width--) {
@@ -3750,10 +3751,17 @@ LibraryManager.library = {
* implementation (replaced by dlmalloc normally) so
* not an issue.
*/
- var ptr = Runtime.staticAlloc(bytes + 8);
+#if ASSERTIONS
+ Runtime.warnOnce('using stub malloc (reference it from C to have the real one included)');
+#endif
+ var ptr = Runtime.dynamicAlloc(bytes + 8);
return (ptr+8) & 0xFFFFFFF8;
},
- free: function(){},
+ free: function() {
+#if ASSERTIONS
+ Runtime.warnOnce('using stub free (reference it from C to have the real one included)');
+#endif
+},
calloc__deps: ['malloc'],
calloc: function(n, s) {
@@ -4029,7 +4037,7 @@ LibraryManager.library = {
_free(temp);
},
- environ: 'allocate(1, "i32*", ALLOC_STACK)',
+ environ: 'allocate(1, "i32*", ALLOC_STATIC)',
__environ__deps: ['environ'],
__environ: '_environ',
__buildEnvironment__deps: ['__environ'],
@@ -4925,7 +4933,7 @@ LibraryManager.library = {
}
return 8;
}
- return 'var ctlz_i8 = allocate([' + range(256).map(function(x) { return ctlz(x) }).join(',') + '], "i8", ALLOC_STACK);';
+ return 'var ctlz_i8 = allocate([' + range(256).map(function(x) { return ctlz(x) }).join(',') + '], "i8", ALLOC_STATIC);';
}],
llvm_ctlz_i32__asm: true,
llvm_ctlz_i32__sig: 'ii',
@@ -4961,7 +4969,7 @@ LibraryManager.library = {
}
return 8;
}
- return 'var cttz_i8 = allocate([' + range(256).map(function(x) { return cttz(x) }).join(',') + '], "i8", ALLOC_STACK);';
+ return 'var cttz_i8 = allocate([' + range(256).map(function(x) { return cttz(x) }).join(',') + '], "i8", ALLOC_STATIC);';
}],
llvm_cttz_i32__asm: true,
llvm_cttz_i32__sig: 'ii',
@@ -5919,11 +5927,11 @@ LibraryManager.library = {
['i32', 'tm_gmtoff'],
['i32', 'tm_zone']]),
// Statically allocated time struct.
- __tm_current: 'allocate({{{ Runtime.QUANTUM_SIZE }}}*26, "i8", ALLOC_STACK)',
+ __tm_current: 'allocate({{{ Runtime.QUANTUM_SIZE }}}*26, "i8", ALLOC_STATIC)',
// Statically allocated timezone strings.
__tm_timezones: {},
// Statically allocated time strings.
- __tm_formatted: 'allocate({{{ Runtime.QUANTUM_SIZE }}}*26, "i8", ALLOC_STACK)',
+ __tm_formatted: 'allocate({{{ Runtime.QUANTUM_SIZE }}}*26, "i8", ALLOC_STATIC)',
mktime__deps: ['__tm_struct_layout', 'tzset'],
mktime: function(tmPtr) {
@@ -6057,9 +6065,9 @@ 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: 'allocate({{{ 2*Runtime.QUANTUM_SIZE }}}, "i32*", ALLOC_STACK)',
- _daylight: 'allocate(1, "i32*", ALLOC_STACK)',
- _timezone: 'allocate(1, "i32*", ALLOC_STACK)',
+ _tzname: 'allocate({{{ 2*Runtime.QUANTUM_SIZE }}}, "i32*", ALLOC_STATIC)',
+ _daylight: 'allocate(1, "i32*", ALLOC_STATIC)',
+ _timezone: 'allocate(1, "i32*", ALLOC_STATIC)',
tzset__deps: ['_tzname', '_daylight', '_timezone'],
tzset: function() {
// TODO: Use (malleable) environment variables instead of system settings.
@@ -6756,15 +6764,18 @@ LibraryManager.library = {
26: 'Text file busy',
18: 'Invalid cross-device link'
},
- __setErrNo__postset: '___setErrNo(0);',
__setErrNo: function(value) {
// For convenient setting and returning of errno.
- if (!___setErrNo.ret) ___setErrNo.ret = allocate([0], 'i32', ALLOC_STATIC);
+ if (!___setErrNo.ret) ___setErrNo.ret = allocate([0], 'i32', ALLOC_NORMAL);
{{{ makeSetValue('___setErrNo.ret', '0', 'value', 'i32') }}}
return value;
},
__errno_location__deps: ['__setErrNo'],
__errno_location: function() {
+ if (!___setErrNo.ret) {
+ ___setErrNo.ret = allocate([0], 'i32', ALLOC_NORMAL);
+ {{{ makeSetValue('___setErrNo.ret', '0', '0', 'i32') }}}
+ }
return ___setErrNo.ret;
},
__errno: '__errno_location',
@@ -6877,7 +6888,7 @@ LibraryManager.library = {
void **restrict stackaddr, size_t *restrict stacksize); */
/*FIXME: assumes that there is only one thread, and that attr is the
current thread*/
- {{{ makeSetValue('stackaddr', '0', 'STACK_ROOT', 'i8*') }}}
+ {{{ makeSetValue('stackaddr', '0', 'STACK_BASE', 'i8*') }}}
{{{ makeSetValue('stacksize', '0', 'TOTAL_STACK', 'i32') }}}
return 0;
},