aboutsummaryrefslogtreecommitdiff
path: root/src/library.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/library.js')
-rw-r--r--src/library.js446
1 files changed, 137 insertions, 309 deletions
diff --git a/src/library.js b/src/library.js
index 91d5f925..c2830397 100644
--- a/src/library.js
+++ b/src/library.js
@@ -325,6 +325,9 @@ LibraryManager.library = {
// int mkdir(const char *path, mode_t mode);
// http://pubs.opengroup.org/onlinepubs/7908799/xsh/mkdir.html
path = Pointer_stringify(path);
+ // remove a trailing slash, if one - /a/b/ has basename of '', but
+ // we want to create b in the context of this function
+ if (path[path.length-1] === '/') path = path.substr(0, path.length-1);
try {
FS.mkdir(path, mode, 0);
return 0;
@@ -1861,14 +1864,14 @@ LibraryManager.library = {
// int x = 4; printf("%c\n", (char)x);
var ret;
if (type === 'double') {
-#if TARGET_LE32 == 2
+#if TARGET_ASMJS_UNKNOWN_EMSCRIPTEN == 2
ret = {{{ makeGetValue('varargs', 'argIndex', 'double', undefined, undefined, true, 4) }}};
#else
ret = {{{ makeGetValue('varargs', 'argIndex', 'double', undefined, undefined, true) }}};
#endif
#if USE_TYPED_ARRAYS == 2
} else if (type == 'i64') {
-#if TARGET_LE32 == 1
+#if TARGET_ASMJS_UNKNOWN_EMSCRIPTEN == 1
ret = [{{{ makeGetValue('varargs', 'argIndex', 'i32', undefined, undefined, true) }}},
{{{ makeGetValue('varargs', 'argIndex+8', 'i32', undefined, undefined, true) }}}];
argIndex += {{{ STACK_ALIGN }}}; // each 32-bit chunk is in a 64-bit block
@@ -1885,7 +1888,7 @@ LibraryManager.library = {
type = 'i32'; // varargs are always i32, i64, or double
ret = {{{ makeGetValue('varargs', 'argIndex', 'i32', undefined, undefined, true) }}};
}
-#if TARGET_LE32 == 2
+#if TARGET_ASMJS_UNKNOWN_EMSCRIPTEN == 2
argIndex += Runtime.getNativeFieldSize(type);
#else
argIndex += Math.max(Runtime.getNativeFieldSize(type), Runtime.getAlignSize(type, null, true));
@@ -2420,7 +2423,9 @@ LibraryManager.library = {
fileno: function(stream) {
// int fileno(FILE *stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fileno.html
- return FS.getStreamFromPtr(stream).fd;
+ stream = FS.getStreamFromPtr(stream);
+ if (!stream) return -1;
+ return stream.fd;
},
ftrylockfile: function() {
// int ftrylockfile(FILE *file);
@@ -2859,7 +2864,7 @@ LibraryManager.library = {
vsscanf: 'sscanf',
#endif
-#if TARGET_LE32
+#if TARGET_ASMJS_UNKNOWN_EMSCRIPTEN
// convert va_arg into varargs
vfprintf__deps: ['fprintf'],
vfprintf: function(s, f, va_arg) {
@@ -3033,34 +3038,6 @@ LibraryManager.library = {
Module['abort']();
},
- bsearch: function(key, base, num, size, compar) {
- function cmp(x, y) {
-#if ASM_JS
- return Module['dynCall_iii'](compar, x, y);
-#else
- return FUNCTION_TABLE[compar](x, y);
-#endif
- };
- var left = 0;
- var right = num;
- var mid, test, addr;
-
- while (left < right) {
- mid = (left + right) >>> 1;
- addr = base + (mid * size);
- test = cmp(key, addr);
- if (test < 0) {
- right = mid;
- } else if (test > 0) {
- left = mid + 1;
- } else {
- return addr;
- }
- }
-
- return 0;
- },
-
realloc__deps: ['malloc', 'memcpy', 'free'],
realloc: function(ptr, size) {
// Very simple, inefficient implementation - if you use a real malloc, best to use
@@ -3264,41 +3241,6 @@ LibraryManager.library = {
return _strtoull(str, endptr, base); // no locale support yet
},
- atoi__deps: ['strtol'],
- atoi: function(ptr) {
- return _strtol(ptr, null, 10);
- },
- atol: 'atoi',
-
- atoll__deps: ['strtoll'],
- atoll: function(ptr) {
- return _strtoll(ptr, null, 10);
- },
-
- qsort__deps: ['malloc', 'memcpy', 'free'],
- qsort: function(base, num, size, cmp) {
- if (num == 0 || size == 0) return;
- // forward calls to the JavaScript sort method
- // first, sort the items logically
- var keys = [];
- for (var i = 0; i < num; i++) keys.push(i);
- keys.sort(function(a, b) {
-#if ASM_JS
- return Module['dynCall_iii'](cmp, base+a*size, base+b*size);
-#else
- return FUNCTION_TABLE[cmp](base+a*size, base+b*size);
-#endif
- });
- // apply the sort
- var temp = _malloc(num*size);
- _memcpy(temp, base, num*size);
- for (var i = 0; i < num; i++) {
- if (keys[i] == i) continue; // already in place
- _memcpy(base+i*size, temp+keys[i]*size, size);
- }
- _free(temp);
- },
-
environ: 'allocate(1, "i32*", ALLOC_STATIC)',
__environ__deps: ['environ'],
__environ: '_environ',
@@ -3502,8 +3444,6 @@ LibraryManager.library = {
// string.h
// ==========================================================================
- // FIXME: memcpy, memmove and memset should all return their destination pointers.
-
memcpy__inline: function(dest, src, num, align) {
var ret = '';
#if ASSERTIONS
@@ -3585,13 +3525,6 @@ LibraryManager.library = {
llvm_memmove_p0i8_p0i8_i32: 'memmove',
llvm_memmove_p0i8_p0i8_i64: 'memmove',
- bcopy__deps: ['memmove'],
- bcopy: function(src, dest, num) {
- // void bcopy(const void *s1, void *s2, size_t n);
- // http://pubs.opengroup.org/onlinepubs/009695399/functions/bcopy.html
- _memmove(dest, src, num);
- },
-
memset__inline: function(ptr, value, num, align) {
return makeSetValues(ptr, 0, value, 'null', num, align);
},
@@ -3646,38 +3579,6 @@ LibraryManager.library = {
return (curr - ptr)|0;
},
- strspn: function(pstr, pset) {
- var str = pstr, set, strcurr, setcurr;
- while (1) {
- strcurr = {{{ makeGetValue('str', '0', 'i8') }}};
- if (!strcurr) return str - pstr;
- set = pset;
- while (1) {
- setcurr = {{{ makeGetValue('set', '0', 'i8') }}};
- if (!setcurr || setcurr == strcurr) break;
- set++;
- }
- if (!setcurr) return str - pstr;
- str++;
- }
- },
-
- strcspn: function(pstr, pset) {
- var str = pstr, set, strcurr, setcurr;
- while (1) {
- strcurr = {{{ makeGetValue('str', '0', 'i8') }}};
- if (!strcurr) return str - pstr;
- set = pset;
- while (1) {
- setcurr = {{{ makeGetValue('set', '0', 'i8') }}};
- if (!setcurr || setcurr == strcurr) break;
- set++;
- }
- if (setcurr) return str - pstr;
- str++;
- }
- },
-
strcpy__asm: true,
strcpy__sig: 'iii',
strcpy: function(pdest, psrc) {
@@ -3690,15 +3591,6 @@ LibraryManager.library = {
return pdest|0;
},
- stpcpy: function(pdest, psrc) {
- var i = 0;
- do {
- {{{ makeCopyValues('pdest+i', 'psrc+i', 1, 'i8', null, 1) }}};
- i ++;
- } while ({{{ makeGetValue('psrc', 'i-1', 'i8') }}} != 0);
- return pdest + i - 1;
- },
-
strncpy__asm: true,
strncpy__sig: 'iiii',
strncpy: function(pdest, psrc, num) {
@@ -3750,184 +3642,6 @@ LibraryManager.library = {
return pdest|0;
},
- strncat__deps: ['strlen'],
- strncat: function(pdest, psrc, num) {
- var len = _strlen(pdest);
- var i = 0;
- while(1) {
- {{{ makeCopyValues('pdest+len+i', 'psrc+i', 1, 'i8', null, 1) }}};
- if ({{{ makeGetValue('pdest', 'len+i', 'i8') }}} == 0) break;
- i ++;
- if (i == num) {
- {{{ makeSetValue('pdest', 'len+i', 0, 'i8') }}};
- break;
- }
- }
- return pdest;
- },
-
- memchr: function(ptr, chr, num) {
- chr = unSign(chr);
- for (var i = 0; i < num; i++) {
- if ({{{ makeGetValue('ptr', 0, 'i8') }}} == chr) return ptr;
- ptr++;
- }
- return 0;
- },
-
- strnlen: function(ptr, num) {
- num = num >>> 0;
- for (var i = 0; i < num; i++) {
- if ({{{ makeGetValue('ptr', 0, 'i8') }}} == 0) return i;
- ptr++;
- }
- return num;
- },
-
- strstr: function(ptr1, ptr2) {
- var check = 0, start;
- do {
- if (!check) {
- start = ptr1;
- check = ptr2;
- }
- var curr1 = {{{ makeGetValue('ptr1++', 0, 'i8') }}};
- var curr2 = {{{ makeGetValue('check++', 0, 'i8') }}};
- if (curr2 == 0) return start;
- if (curr2 != curr1) {
- // rewind to one character after start, to find ez in eeez
- ptr1 = start + 1;
- check = 0;
- }
- } while (curr1);
- return 0;
- },
-
- strchr: function(ptr, chr) {
- ptr--;
- do {
- ptr++;
- var val = {{{ makeGetValue('ptr', 0, 'i8') }}};
- if (val == chr) return ptr;
- } while (val);
- return 0;
- },
- index: 'strchr',
-
- strrchr__deps: ['strlen'],
- strrchr: function(ptr, chr) {
- var ptr2 = ptr + _strlen(ptr);
- do {
- if ({{{ makeGetValue('ptr2', 0, 'i8') }}} == chr) return ptr2;
- ptr2--;
- } while (ptr2 >= ptr);
- return 0;
- },
- rindex: 'strrchr',
-
- strdup__deps: ['strlen', 'malloc'],
- strdup: function(ptr) {
- var len = _strlen(ptr);
- var newStr = _malloc(len + 1);
- {{{ makeCopyValues('newStr', 'ptr', 'len', 'null', null, 1) }}};
- {{{ makeSetValue('newStr', 'len', '0', 'i8') }}};
- return newStr;
- },
-
- strndup__deps: ['strdup', 'strlen', 'malloc'],
- strndup: function(ptr, size) {
- var len = _strlen(ptr);
-
- if (size >= len) {
- return _strdup(ptr);
- }
-
- if (size < 0) {
- size = 0;
- }
-
- var newStr = _malloc(size + 1);
- {{{ makeCopyValues('newStr', 'ptr', 'size', 'null', null, 1) }}};
- {{{ makeSetValue('newStr', 'size', '0', 'i8') }}};
- return newStr;
- },
-
- strpbrk: function(ptr1, ptr2) {
- var curr;
- var searchSet = {};
- while (1) {
- var curr = {{{ makeGetValue('ptr2++', 0, 'i8') }}};
- if (!curr) break;
- searchSet[curr] = 1;
- }
- while (1) {
- curr = {{{ makeGetValue('ptr1', 0, 'i8') }}};
- if (!curr) break;
- if (curr in searchSet) return ptr1;
- ptr1++;
- }
- return 0;
- },
-
- __strtok_state: 0,
- strtok__deps: ['__strtok_state', 'strtok_r'],
- strtok__postset: '___strtok_state = Runtime.staticAlloc(4);',
- strtok: function(s, delim) {
- return _strtok_r(s, delim, ___strtok_state);
- },
-
- // Translated from newlib; for the original source and licensing, see library_strtok_r.c
- strtok_r: function(s, delim, lasts) {
- var skip_leading_delim = 1;
- var spanp;
- var c, sc;
- var tok;
-
-
- if (s == 0 && (s = getValue(lasts, 'i8*')) == 0) {
- return 0;
- }
-
- cont: while (1) {
- c = getValue(s++, 'i8');
- for (spanp = delim; (sc = getValue(spanp++, 'i8')) != 0;) {
- if (c == sc) {
- if (skip_leading_delim) {
- continue cont;
- } else {
- setValue(lasts, s, 'i8*');
- setValue(s - 1, 0, 'i8');
- return s - 1;
- }
- }
- }
- break;
- }
-
- if (c == 0) {
- setValue(lasts, 0, 'i8*');
- return 0;
- }
- tok = s - 1;
-
- for (;;) {
- c = getValue(s++, 'i8');
- spanp = delim;
- do {
- if ((sc = getValue(spanp++, 'i8')) == c) {
- if (c == 0) {
- s = 0;
- } else {
- setValue(s - 1, 0, 'i8');
- }
- setValue(lasts, s, 'i8*');
- return tok;
- }
- } while (sc != 0);
- }
- abort('strtok_r error!');
- },
-
strerror_r__deps: ['$ERRNO_CODES', '$ERRNO_MESSAGES', '__setErrNo'],
strerror_r: function(errnum, strerrbuf, buflen) {
if (errnum in ERRNO_MESSAGES) {
@@ -4178,7 +3892,7 @@ LibraryManager.library = {
#if TARGET_X86
return makeSetValue(ptr, 0, 'varrp', 'void*');
#endif
-#if TARGET_LE32
+#if TARGET_ASMJS_UNKNOWN_EMSCRIPTEN
// 2-word structure: struct { void* start; void* currentOffset; }
return makeSetValue(ptr, 0, 'varrp', 'void*') + ';' + makeSetValue(ptr, Runtime.QUANTUM_SIZE, 0, 'void*');
#endif
@@ -4194,12 +3908,18 @@ LibraryManager.library = {
{{{ makeCopyValues('(ppdest+'+Runtime.QUANTUM_SIZE+')', '(ppsrc+'+Runtime.QUANTUM_SIZE+')', Runtime.QUANTUM_SIZE, 'null', null, 1) }}};
},
+ llvm_bswap_i16__asm: true,
+ llvm_bswap_i16__sig: 'ii',
llvm_bswap_i16: function(x) {
- return ((x&0xff)<<8) | ((x>>8)&0xff);
+ x = x|0;
+ return (((x&0xff)<<8) | ((x>>8)&0xff))|0;
},
+ llvm_bswap_i32__asm: true,
+ llvm_bswap_i32__sig: 'ii',
llvm_bswap_i32: function(x) {
- return ((x&0xff)<<24) | (((x>>8)&0xff)<<16) | (((x>>16)&0xff)<<8) | (x>>>24);
+ x = x|0;
+ return (((x&0xff)<<24) | (((x>>8)&0xff)<<16) | (((x>>16)&0xff)<<8) | (x>>>24))|0;
},
llvm_bswap_i64__deps: ['llvm_bswap_i32'],
@@ -4584,6 +4304,7 @@ LibraryManager.library = {
// Destructors for std::exception since we don't have them implemented in libcxx as we aren't using libcxxabi.
// These are also needed for the dlmalloc tests.
+ _ZNSt9exceptionD0Ev: function() {},
_ZNSt9exceptionD1Ev: function() {},
_ZNSt9exceptionD2Ev: function() {},
@@ -4597,8 +4318,6 @@ LibraryManager.library = {
return __ZNKSt9exception4whatEv.buffer;
},
- _ZNSt9type_infoD2Ev: function(){},
-
// RTTI hacks for exception handling, defining type_infos for common types.
// The values are dummies. We simply use the addresses of these statically
// allocated variables as unique identifiers.
@@ -4717,6 +4436,89 @@ LibraryManager.library = {
llvm_nacl_atomic_store_i32__inline: true,
+ // gnu atomics
+
+ __atomic_is_lock_free: function(size, ptr) {
+ return size <= 4 && (ptr&(size-1)) == 0;
+ },
+
+ __atomic_load_8: function(ptr, memmodel) {
+ {{{ makeStructuralReturn([makeGetValue('ptr', 0, 'i32'), makeGetValue('ptr', 4, 'i32')]) }}};
+ },
+
+ __atomic_store_8: function(ptr, vall, valh, memmodel) {
+ {{{ makeSetValue('ptr', 0, 'vall', 'i32') }}};
+ {{{ makeSetValue('ptr', 4, 'valh', 'i32') }}};
+ },
+
+ __atomic_exchange_8: function(ptr, vall, valh, memmodel) {
+ var l = {{{ makeGetValue('ptr', 0, 'i32') }}};
+ var h = {{{ makeGetValue('ptr', 4, 'i32') }}};
+ {{{ makeSetValue('ptr', 0, 'vall', 'i32') }}};
+ {{{ makeSetValue('ptr', 4, 'valh', 'i32') }}};
+ {{{ makeStructuralReturn(['l', 'h']) }}};
+ },
+
+ __atomic_compare_exchange_8: function(ptr, expected, desiredl, desiredh, weak, success_memmodel, failure_memmodel) {
+ var pl = {{{ makeGetValue('ptr', 0, 'i32') }}};
+ var ph = {{{ makeGetValue('ptr', 4, 'i32') }}};
+ var el = {{{ makeGetValue('expected', 0, 'i32') }}};
+ var eh = {{{ makeGetValue('expected', 4, 'i32') }}};
+ if (pl === el && ph === eh) {
+ {{{ makeSetValue('ptr', 0, 'desiredl', 'i32') }}};
+ {{{ makeSetValue('ptr', 4, 'desiredh', 'i32') }}};
+ return 1;
+ } else {
+ {{{ makeSetValue('expected', 0, 'pl', 'i32') }}};
+ {{{ makeSetValue('expected', 4, 'ph', 'i32') }}};
+ return 0;
+ }
+ },
+
+ __atomic_fetch_add_8__deps: ['llvm_uadd_with_overflow_i64'],
+ __atomic_fetch_add_8: function(ptr, vall, valh, memmodel) {
+ var l = {{{ makeGetValue('ptr', 0, 'i32') }}};
+ var h = {{{ makeGetValue('ptr', 4, 'i32') }}};
+ {{{ makeSetValue('ptr', 0, '_llvm_uadd_with_overflow_i64(l, h, vall, valh)', 'i32') }}};
+ {{{ makeSetValue('ptr', 4, 'tempRet0', 'i32') }}};
+ {{{ makeStructuralReturn(['l', 'h']) }}};
+ },
+
+ __atomic_fetch_sub_8__deps: ['i64Subtract'],
+ __atomic_fetch_sub_8: function(ptr, vall, valh, memmodel) {
+ var l = {{{ makeGetValue('ptr', 0, 'i32') }}};
+ var h = {{{ makeGetValue('ptr', 4, 'i32') }}};
+ {{{ makeSetValue('ptr', 0, '_i64Subtract(l, h, vall, valh)', 'i32') }}};
+ {{{ makeSetValue('ptr', 4, 'tempRet0', 'i32') }}};
+ {{{ makeStructuralReturn(['l', 'h']) }}};
+ },
+
+ __atomic_fetch_and_8__deps: ['i64Subtract'],
+ __atomic_fetch_and_8: function(ptr, vall, valh, memmodel) {
+ var l = {{{ makeGetValue('ptr', 0, 'i32') }}};
+ var h = {{{ makeGetValue('ptr', 4, 'i32') }}};
+ {{{ makeSetValue('ptr', 0, 'l&vall', 'i32') }}};
+ {{{ makeSetValue('ptr', 4, 'h&valh', 'i32') }}};
+ {{{ makeStructuralReturn(['l', 'h']) }}};
+ },
+
+ __atomic_fetch_or_8: function(ptr, vall, valh, memmodel) {
+ var l = {{{ makeGetValue('ptr', 0, 'i32') }}};
+ var h = {{{ makeGetValue('ptr', 4, 'i32') }}};
+ {{{ makeSetValue('ptr', 0, 'l|vall', 'i32') }}};
+ {{{ makeSetValue('ptr', 4, 'h|valh', 'i32') }}};
+ {{{ makeStructuralReturn(['l', 'h']) }}};
+ },
+
+ __atomic_fetch_xor_8: function(ptr, vall, valh, memmodel) {
+ var l = {{{ makeGetValue('ptr', 0, 'i32') }}};
+ var h = {{{ makeGetValue('ptr', 4, 'i32') }}};
+ {{{ makeSetValue('ptr', 0, 'l^vall', 'i32') }}};
+ {{{ makeSetValue('ptr', 4, 'h^valh', 'i32') }}};
+ {{{ makeStructuralReturn(['l', 'h']) }}};
+ },
+
+
// ==========================================================================
// llvm-mono integration
// ==========================================================================
@@ -6399,6 +6201,13 @@ LibraryManager.library = {
siginterrupt: function() { throw 'siginterrupt not implemented' },
+ raise__deps: ['$ERRNO_CODES', '__setErrNo'],
+ raise: function(sig) {
+ // TODO:
+ ___setErrNo(ERRNO_CODES.ENOSYS);
+ return -1;
+ },
+
// ==========================================================================
// sys/wait.h
// ==========================================================================
@@ -8166,7 +7975,9 @@ LibraryManager.library = {
},
setsockopt: function(d, level, optname, optval, optlen) {
+#if SOCKET_DEBUG
console.log('ignoring setsockopt command');
+#endif
return 0;
},
@@ -8655,7 +8466,9 @@ LibraryManager.library = {
},
setsockopt: function(fd, level, optname, optval, optlen) {
+#if SOCKET_DEBUG
console.log('ignoring setsockopt command');
+#endif
return 0;
},
@@ -8912,10 +8725,19 @@ LibraryManager.library = {
emscripten_get_callstack_js: function(flags) {
var err = new Error();
if (!err.stack) {
- Runtime.warnOnce('emscripten_get_callstack_js is not supported on this browser!');
- return '';
+ // IE10+ special cases: It does have callstack info, but it is only populated if an Error object is thrown,
+ // so try that as a special-case.
+ try {
+ throw new Error(0);
+ } catch(e) {
+ err = e;
+ }
+ if (!err.stack) {
+ Runtime.warnOnce('emscripten_get_callstack_js is not supported on this browser!');
+ return '';
+ }
}
- var callstack = new Error().stack.toString();
+ var callstack = err.stack.toString();
// Find the symbols in the callstack that corresponds to the functions that report callstack information, and remove everyhing up to these from the output.
var iThisFunc = callstack.lastIndexOf('_emscripten_log');
@@ -8941,7 +8763,8 @@ LibraryManager.library = {
// Process all lines:
lines = callstack.split('\n');
callstack = '';
- var firefoxRe = new RegExp('\\s*(.*?)@(.*):(.*)'); // Extract components of form ' Object._main@http://server.com:4324'
+ var newFirefoxRe = new RegExp('\\s*(.*?)@(.*?):([0-9]+):([0-9]+)'); // New FF30 with column info: extract components of form ' Object._main@http://server.com:4324:12'
+ var firefoxRe = new RegExp('\\s*(.*?)@(.*):(.*)(:(.*))?'); // Old FF without column info: extract components of form ' Object._main@http://server.com:4324'
var chromeRe = new RegExp('\\s*at (.*?) \\\((.*):(.*):(.*)\\\)'); // Extract components of form ' at Object._main (http://server.com/file.html:4324:12)'
for(l in lines) {
@@ -8959,12 +8782,13 @@ LibraryManager.library = {
lineno = parts[3];
column = parts[4];
} else {
- parts = firefoxRe.exec(line);
- if (parts && parts.length == 4) {
+ parts = newFirefoxRe.exec(line);
+ if (!parts) parts = firefoxRe.exec(line);
+ if (parts && parts.length >= 4) {
jsSymbolName = parts[1];
file = parts[2];
lineno = parts[3];
- column = 0; // Firefox doesn't carry column information. See https://bugzilla.mozilla.org/show_bug.cgi?id=762556
+ column = parts[4]|0; // Old Firefox doesn't carry column information, but in new FF30, it is present. See https://bugzilla.mozilla.org/show_bug.cgi?id=762556
} else {
// Was not able to extract this line for demangling/sourcemapping purposes. Output it as-is.
callstack += line + '\n';
@@ -9020,7 +8844,7 @@ LibraryManager.library = {
}
// Truncate output to avoid writing past bounds.
if (callstack.length > maxbytes-1) {
- callstack.slice(0, maxbytes-1);
+ callstack = callstack.slice(0, maxbytes-1);
}
// Output callstack string as C string to HEAP.
writeStringToMemory(callstack, str, false);
@@ -9109,6 +8933,10 @@ LibraryManager.library = {
#endif
#endif
+ emscripten_debugger: function() {
+ debugger;
+ },
+
//============================
// emscripten vector ops
//============================