aboutsummaryrefslogtreecommitdiff
path: root/src/library.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/library.js')
-rw-r--r--src/library.js149
1 files changed, 91 insertions, 58 deletions
diff --git a/src/library.js b/src/library.js
index ffac685b..1676a82c 100644
--- a/src/library.js
+++ b/src/library.js
@@ -2491,6 +2491,17 @@ LibraryManager.library = {
continue;
}
+ // TODO: Support strings like "%5c" etc.
+ if (format[formatIndex] === '%' && format[formatIndex+1] == 'c') {
+ var argPtr = {{{ makeGetValue('varargs', 'argIndex', 'void*') }}};
+ argIndex += Runtime.getNativeFieldSize('void*');
+ fields++;
+ next = get();
+ {{{ makeSetValue('argPtr', 0, 'next', 'i8') }}}
+ formatIndex += 2;
+ continue;
+ }
+
// remove whitespace
while (1) {
next = get();
@@ -3352,14 +3363,15 @@ LibraryManager.library = {
___setErrNo(ERRNO_CODES.ECHILD);
return -1;
},
- perror__deps: ['puts', 'putc', 'strerror', '__errno_location'],
+ perror__deps: ['puts', 'fputs', 'fputc', 'strerror', '__errno_location'],
perror: function(s) {
// void perror(const char *s);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/perror.html
+ var stdout = {{{ makeGetValue(makeGlobalUse('_stdout'), '0', 'void*') }}};
if (s) {
- _puts(s);
- _putc(':'.charCodeAt(0));
- _putc(' '.charCodeAt(0));
+ _fputs(s, stdout);
+ _fputc(':'.charCodeAt(0), stdout);
+ _fputc(' '.charCodeAt(0), stdout);
}
var errnum = {{{ makeGetValue('___errno_location()', '0', 'i32') }}};
_puts(_strerror(errnum));
@@ -4302,8 +4314,9 @@ LibraryManager.library = {
ptr = ptr|0; value = value|0; num = num|0;
var stop = 0, value4 = 0, stop4 = 0, unaligned = 0;
stop = (ptr + num)|0;
- if (num|0 >= {{{ SEEK_OPTIMAL_ALIGN_MIN }}}) {
+ if ((num|0) >= {{{ SEEK_OPTIMAL_ALIGN_MIN }}}) {
// This is unaligned, but quite large, so work hard to get to aligned settings
+ value = value & 0xff;
unaligned = ptr & 3;
value4 = value | (value << 8) | (value << 16) | (value << 24);
stop4 = stop & ~3;
@@ -4514,11 +4527,16 @@ LibraryManager.library = {
return 0;
},
+ memcmp__asm: 'true',
+ memcmp__sig: 'iiii',
memcmp: function(p1, p2, num) {
- for (var i = 0; i < num; i++) {
- var v1 = {{{ makeGetValue('p1', 'i', 'i8', 0, 1) }}};
- var v2 = {{{ makeGetValue('p2', 'i', 'i8', 0, 1) }}};
- if (v1 != v2) return v1 > v2 ? 1 : -1;
+ p1 = p1|0; p2 = p2|0; num = num|0;
+ var i = 0, v1 = 0, v2 = 0;
+ while ((i|0) < (num|0)) {
+ var v1 = {{{ makeGetValueAsm('p1', 'i', 'i8', true) }}};
+ var v2 = {{{ makeGetValueAsm('p2', 'i', 'i8', true) }}};
+ if ((v1|0) != (v2|0)) return ((v1|0) > (v2|0) ? 1 : -1)|0;
+ i = (i+1)|0;
}
return 0;
},
@@ -4619,10 +4637,8 @@ LibraryManager.library = {
__strtok_state: 0,
strtok__deps: ['__strtok_state', 'strtok_r'],
+ strtok__postset: '___strtok_state = Runtime.staticAlloc(4);',
strtok: function(s, delim) {
- if (!___strtok_state) {
- ___strtok_state = _malloc(4);
- }
return _strtok_r(s, delim, ___strtok_state);
},
@@ -5082,6 +5098,7 @@ LibraryManager.library = {
},
__cxa_call_unexpected: function(exception) {
+ Module.printErr('Unexpected exception thrown, this is not properly supported - aborting');
ABORT = true;
throw exception;
},
@@ -6686,6 +6703,9 @@ LibraryManager.library = {
pthread_mutexattr_destroy: function() {},
pthread_mutex_lock: function() {},
pthread_mutex_unlock: function() {},
+ pthread_mutex_trylock: function() {
+ return 0;
+ },
pthread_cond_init: function() {},
pthread_cond_destroy: function() {},
pthread_cond_broadcast: function() {},
@@ -6728,17 +6748,27 @@ LibraryManager.library = {
pthread_key_create: function(key, destructor) {
if (!_pthread_key_create.keys) _pthread_key_create.keys = {};
- _pthread_key_create.keys[key] = null;
+ // values start at 0
+ _pthread_key_create.keys[key] = 0;
},
pthread_getspecific: function(key) {
- return _pthread_key_create.keys[key];
+ return _pthread_key_create.keys[key] || 0;
},
pthread_setspecific: function(key, value) {
_pthread_key_create.keys[key] = value;
},
+ pthread_key_delete: ['$ERRNO_CODES'],
+ pthread_key_delete: function(key) {
+ if (_pthread_key_create.keys[key]) {
+ delete _pthread_key_create.keys[key];
+ return 0;
+ }
+ return ERRNO_CODES.EINVAL;
+ },
+
pthread_cleanup_push: function(routine, arg) {
__ATEXIT__.push({ func: function() { Runtime.dynCall('vi', routine, [arg]) } })
_pthread_cleanup_push.level = __ATEXIT__.length;
@@ -7243,23 +7273,56 @@ LibraryManager.library = {
},
select: function(nfds, readfds, writefds, exceptfds, timeout) {
- // only readfds are supported, not writefds or exceptfds
+ // readfds are supported,
+ // writefds checks socket open status
+ // exceptfds not supported
// timeout is always 0 - fully async
- assert(!writefds && !exceptfds);
- var ret = 0;
- var l = {{{ makeGetValue('readfds', 0, 'i32') }}};
- var h = {{{ makeGetValue('readfds', 4, 'i32') }}};
- nfds = Math.min(64, nfds); // fd sets have 64 bits
- for (var fd = 0; fd < nfds; fd++) {
- var bit = fd % 32, int = fd < 32 ? l : h;
- if (int & (1 << bit)) {
- // index is in the set, check if it is ready for read
- var info = Sockets.fds[fd];
- if (!info) continue;
- if (info.hasData()) ret++;
+ assert(!exceptfds);
+
+ function canRead(info) {
+ // make sure hasData exists.
+ // we do create it when the socket is connected,
+ // but other implementations may create it lazily
+ return info.hasData && info.hasData();
+ }
+
+ function canWrite(info) {
+ // make sure socket exists.
+ // we do create it when the socket is connected,
+ // but other implementations may create it lazily
+ return info.socket && (info.socket.readyState == info.socket.OPEN);
+ }
+
+ function checkfds(nfds, fds, can) {
+ if (!fds) return 0;
+
+ var bitsSet = 0;
+ var dstLow = 0;
+ var dstHigh = 0;
+ var srcLow = {{{ makeGetValue('fds', 0, 'i32') }}};
+ var srcHigh = {{{ makeGetValue('fds', 4, 'i32') }}};
+ nfds = Math.min(64, nfds); // fd sets have 64 bits
+
+ for (var fd = 0; fd < nfds; fd++) {
+ var mask = 1 << (fd % 32), int = fd < 32 ? srcLow : srcHigh;
+ if (int & mask) {
+ // index is in the set, check if it is ready for read
+ var info = Sockets.fds[fd];
+ if (info && can(info)) {
+ // set bit
+ fd < 32 ? (dstLow = dstLow | mask) : (dstHigh = dstHigh | mask);
+ bitsSet++;
+ }
+ }
}
+
+ {{{ makeSetValue('fds', 0, 'dstLow', 'i32') }}};
+ {{{ makeSetValue('fds', 4, 'dstHigh', 'i32') }}};
+ return bitsSet;
}
- return ret;
+
+ return checkfds(nfds, readfds, canRead)
+ + checkfds(nfds, writefds, canWrite);
},
// pty.h
@@ -7305,36 +7368,6 @@ LibraryManager.library = {
emscripten_random: function() {
return Math.random();
},
-
- $Profiling: {
- max_: 0,
- times: null,
- invalid: 0,
- dump: function() {
- if (Profiling.invalid) {
- Module.printErr('Invalid # of calls to Profiling begin and end!');
- return;
- }
- Module.printErr('Profiling data:')
- for (var i = 0; i < Profiling.max_; i++) {
- Module.printErr('Block ' + i + ': ' + Profiling.times[i]);
- }
- }
- },
- EMSCRIPTEN_PROFILE_INIT__deps: ['$Profiling'],
- EMSCRIPTEN_PROFILE_INIT: function(max_) {
- Profiling.max_ = max_;
- Profiling.times = new Array(max_);
- for (var i = 0; i < max_; i++) Profiling.times[i] = 0;
- },
- EMSCRIPTEN_PROFILE_BEGIN__inline: function(id) {
- return 'Profiling.times[' + id + '] -= Date.now();'
- + 'Profiling.invalid++;'
- },
- EMSCRIPTEN_PROFILE_END__inline: function(id) {
- return 'Profiling.times[' + id + '] += Date.now();'
- + 'Profiling.invalid--;'
- }
};
function autoAddDeps(object, name) {