aboutsummaryrefslogtreecommitdiff
path: root/src/library.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/library.js')
-rw-r--r--src/library.js501
1 files changed, 281 insertions, 220 deletions
diff --git a/src/library.js b/src/library.js
index 1cd7e3f5..45187d8d 100644
--- a/src/library.js
+++ b/src/library.js
@@ -504,7 +504,7 @@ LibraryManager.library = {
}
var utf8 = new Runtime.UTF8Processor();
function simpleOutput(val) {
- if (val === null || val === '\n'.charCodeAt(0)) {
+ if (val === null || val === {{{ charCode('\n') }}}) {
output.printer(output.buffer.join(''));
output.buffer = [];
} else {
@@ -600,8 +600,8 @@ LibraryManager.library = {
quit: function() {
if (!FS.init.initialized) return;
// Flush any partially-printed lines in stdout and stderr. Careful, they may have been closed
- if (FS.streams[2] && FS.streams[2].object.output.buffer.length > 0) FS.streams[2].object.output('\n'.charCodeAt(0));
- if (FS.streams[3] && FS.streams[3].object.output.buffer.length > 0) FS.streams[3].object.output('\n'.charCodeAt(0));
+ if (FS.streams[2] && FS.streams[2].object.output.buffer.length > 0) FS.streams[2].object.output({{{ charCode('\n') }}});
+ if (FS.streams[3] && FS.streams[3].object.output.buffer.length > 0) FS.streams[3].object.output({{{ charCode('\n') }}});
},
// Standardizes a path. Useful for making comparisons of pathnames work in a consistent manner.
@@ -828,11 +828,11 @@ LibraryManager.library = {
// Null or empty results in '.'.
var me = ___libgenSplitName;
if (!me.ret) {
- me.ret = allocate(['.'.charCodeAt(0), 0], 'i8', ALLOC_NORMAL);
+ me.ret = allocate([{{{ charCode('.') }}}, 0], 'i8', ALLOC_NORMAL);
}
return [me.ret, -1];
} else {
- var slash = '/'.charCodeAt(0);
+ var slash = {{{ charCode('/') }}};
var allSlashes = true;
var slashPositions = [];
for (var i = 0; {{{ makeGetValue('path', 'i', 'i8') }}} !== 0; i++) {
@@ -1730,7 +1730,12 @@ LibraryManager.library = {
}
var contents = stream.object.contents;
var size = Math.min(contents.length - offset, nbyte);
- if (contents.subarray || contents.slice) { // typed array or normal array
+#if USE_TYPED_ARRAYS == 2
+ if (contents.subarray) { // typed array
+ HEAPU8.set(contents.subarray(offset, offset+size), buf);
+ } else
+#endif
+ if (contents.slice) { // normal array
for (var i = 0; i < size; i++) {
{{{ makeSetValue('buf', 'i', 'contents[offset + i]', 'i8') }}}
}
@@ -2403,6 +2408,7 @@ LibraryManager.library = {
case {{{ cDefine('_SC_STREAM_MAX') }}}: return 16;
case {{{ cDefine('_SC_TZNAME_MAX') }}}: return 6;
case {{{ cDefine('_SC_THREAD_DESTRUCTOR_ITERATIONS') }}}: return 4;
+ case {{{ cDefine('_SC_NPROCESSORS_ONLN') }}}: return 1;
}
___setErrNo(ERRNO_CODES.EINVAL);
return -1;
@@ -2451,9 +2457,9 @@ LibraryManager.library = {
_scanString: function(format, get, unget, varargs) {
if (!__scanString.whiteSpace) {
__scanString.whiteSpace = {};
- __scanString.whiteSpace[' '.charCodeAt(0)] = 1;
- __scanString.whiteSpace['\t'.charCodeAt(0)] = 1;
- __scanString.whiteSpace['\n'.charCodeAt(0)] = 1;
+ __scanString.whiteSpace[{{{ charCode(' ') }}}] = 1;
+ __scanString.whiteSpace[{{{ charCode('\t') }}}] = 1;
+ __scanString.whiteSpace[{{{ charCode('\n') }}}] = 1;
__scanString.whiteSpace[' '] = 1;
__scanString.whiteSpace['\t'] = 1;
__scanString.whiteSpace['\n'] = 1;
@@ -2513,8 +2519,8 @@ LibraryManager.library = {
if (format[formatIndex] === '%') {
formatIndex++;
var maxSpecifierStart = formatIndex;
- while (format[formatIndex].charCodeAt(0) >= '0'.charCodeAt(0) &&
- format[formatIndex].charCodeAt(0) <= '9'.charCodeAt(0)) {
+ while (format[formatIndex].charCodeAt(0) >= {{{ charCode('0') }}} &&
+ format[formatIndex].charCodeAt(0) <= {{{ charCode('9') }}}) {
formatIndex++;
}
var max_;
@@ -2560,11 +2566,11 @@ LibraryManager.library = {
while ((curr < max_ || isNaN(max_)) && next > 0) {
if (!(next in __scanString.whiteSpace) && // stop on whitespace
(type == 's' ||
- ((type === 'd' || type == 'u' || type == 'i') && ((next >= '0'.charCodeAt(0) && next <= '9'.charCodeAt(0)) ||
- (first && next == '-'.charCodeAt(0)))) ||
- (type === 'x' && (next >= '0'.charCodeAt(0) && next <= '9'.charCodeAt(0) ||
- next >= 'a'.charCodeAt(0) && next <= 'f'.charCodeAt(0) ||
- next >= 'A'.charCodeAt(0) && next <= 'F'.charCodeAt(0)))) &&
+ ((type === 'd' || type == 'u' || type == 'i') && ((next >= {{{ charCode('0') }}} && next <= {{{ charCode('9') }}}) ||
+ (first && next == {{{ charCode('-') }}}))) ||
+ (type === 'x' && (next >= {{{ charCode('0') }}} && next <= {{{ charCode('9') }}} ||
+ next >= {{{ charCode('a') }}} && next <= {{{ charCode('f') }}} ||
+ next >= {{{ charCode('A') }}} && next <= {{{ charCode('F') }}}))) &&
(formatIndex >= format.length || next !== format[formatIndex].charCodeAt(0))) { // Stop when we read something that is coming up
buffer.push(String.fromCharCode(next));
next = get();
@@ -2669,7 +2675,7 @@ LibraryManager.library = {
curr = {{{ makeGetValue(0, 'textIndex', 'i8') }}};
if (curr === 0) break;
next = {{{ makeGetValue(0, 'textIndex+1', 'i8') }}};
- if (curr == '%'.charCodeAt(0)) {
+ if (curr == {{{ charCode('%') }}}) {
// Handle flags.
var flagAlwaysSigned = false;
var flagLeftAlign = false;
@@ -2677,16 +2683,16 @@ LibraryManager.library = {
var flagZeroPad = false;
flagsLoop: while (1) {
switch (next) {
- case '+'.charCodeAt(0):
+ case {{{ charCode('+') }}}:
flagAlwaysSigned = true;
break;
- case '-'.charCodeAt(0):
+ case {{{ charCode('-') }}}:
flagLeftAlign = true;
break;
- case '#'.charCodeAt(0):
+ case {{{ charCode('#') }}}:
flagAlternative = true;
break;
- case '0'.charCodeAt(0):
+ case {{{ charCode('0') }}}:
if (flagZeroPad) {
break flagsLoop;
} else {
@@ -2702,13 +2708,13 @@ LibraryManager.library = {
// Handle width.
var width = 0;
- if (next == '*'.charCodeAt(0)) {
+ if (next == {{{ charCode('*') }}}) {
width = getNextArg('i32');
textIndex++;
next = {{{ makeGetValue(0, 'textIndex+1', 'i8') }}};
} else {
- while (next >= '0'.charCodeAt(0) && next <= '9'.charCodeAt(0)) {
- width = width * 10 + (next - '0'.charCodeAt(0));
+ while (next >= {{{ charCode('0') }}} && next <= {{{ charCode('9') }}}) {
+ width = width * 10 + (next - {{{ charCode('0') }}});
textIndex++;
next = {{{ makeGetValue(0, 'textIndex+1', 'i8') }}};
}
@@ -2716,20 +2722,20 @@ LibraryManager.library = {
// Handle precision.
var precisionSet = false;
- if (next == '.'.charCodeAt(0)) {
+ if (next == {{{ charCode('.') }}}) {
var precision = 0;
precisionSet = true;
textIndex++;
next = {{{ makeGetValue(0, 'textIndex+1', 'i8') }}};
- if (next == '*'.charCodeAt(0)) {
+ if (next == {{{ charCode('*') }}}) {
precision = getNextArg('i32');
textIndex++;
} else {
while(1) {
var precisionChr = {{{ makeGetValue(0, 'textIndex+1', 'i8') }}};
- if (precisionChr < '0'.charCodeAt(0) ||
- precisionChr > '9'.charCodeAt(0)) break;
- precision = precision * 10 + (precisionChr - '0'.charCodeAt(0));
+ if (precisionChr < {{{ charCode('0') }}} ||
+ precisionChr > {{{ charCode('9') }}}) break;
+ precision = precision * 10 + (precisionChr - {{{ charCode('0') }}});
textIndex++;
}
}
@@ -2743,7 +2749,7 @@ LibraryManager.library = {
switch (String.fromCharCode(next)) {
case 'h':
var nextNext = {{{ makeGetValue(0, 'textIndex+2', 'i8') }}};
- if (nextNext == 'h'.charCodeAt(0)) {
+ if (nextNext == {{{ charCode('h') }}}) {
textIndex++;
argSize = 1; // char (actually i32 in varargs)
} else {
@@ -2752,7 +2758,7 @@ LibraryManager.library = {
break;
case 'l':
var nextNext = {{{ makeGetValue(0, 'textIndex+2', 'i8') }}};
- if (nextNext == 'l'.charCodeAt(0)) {
+ if (nextNext == {{{ charCode('l') }}}) {
textIndex++;
argSize = 8; // long long
} else {
@@ -2778,7 +2784,7 @@ LibraryManager.library = {
// Handle type specifier.
if (['d', 'i', 'u', 'o', 'x', 'X', 'p'].indexOf(String.fromCharCode(next)) != -1) {
// Integer.
- var signed = next == 'd'.charCodeAt(0) || next == 'i'.charCodeAt(0);
+ var signed = next == {{{ charCode('d') }}} || next == {{{ charCode('i') }}};
argSize = argSize || 4;
var currArg = getNextArg('i' + (argSize * 8));
#if PRECISE_I64_MATH
@@ -2788,7 +2794,7 @@ LibraryManager.library = {
#if USE_TYPED_ARRAYS == 2
// Flatten i64-1 [low, high] into a (slightly rounded) double
if (argSize == 8) {
- currArg = Runtime.makeBigInt(currArg[0], currArg[1], next == 'u'.charCodeAt(0));
+ currArg = Runtime.makeBigInt(currArg[0], currArg[1], next == {{{ charCode('u') }}});
}
#endif
// Truncate to requested size.
@@ -2799,20 +2805,20 @@ LibraryManager.library = {
// Format the number.
var currAbsArg = Math.abs(currArg);
var prefix = '';
- if (next == 'd'.charCodeAt(0) || next == 'i'.charCodeAt(0)) {
+ if (next == {{{ charCode('d') }}} || next == {{{ charCode('i') }}}) {
#if PRECISE_I64_MATH
if (argSize == 8 && i64Math) argText = i64Math.stringify(origArg[0], origArg[1], null); else
#endif
argText = reSign(currArg, 8 * argSize, 1).toString(10);
- } else if (next == 'u'.charCodeAt(0)) {
+ } else if (next == {{{ charCode('u') }}}) {
#if PRECISE_I64_MATH
if (argSize == 8 && i64Math) argText = i64Math.stringify(origArg[0], origArg[1], true); else
#endif
argText = unSign(currArg, 8 * argSize, 1).toString(10);
currArg = Math.abs(currArg);
- } else if (next == 'o'.charCodeAt(0)) {
+ } else if (next == {{{ charCode('o') }}}) {
argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8);
- } else if (next == 'x'.charCodeAt(0) || next == 'X'.charCodeAt(0)) {
+ } else if (next == {{{ charCode('x') }}} || next == {{{ charCode('X') }}}) {
prefix = flagAlternative ? '0x' : '';
#if PRECISE_I64_MATH
if (argSize == 8 && i64Math) argText = (origArg[1]>>>0).toString(16) + (origArg[0]>>>0).toString(16); else
@@ -2830,11 +2836,11 @@ LibraryManager.library = {
} else {
argText = currAbsArg.toString(16);
}
- if (next == 'X'.charCodeAt(0)) {
+ if (next == {{{ charCode('X') }}}) {
prefix = prefix.toUpperCase();
argText = argText.toUpperCase();
}
- } else if (next == 'p'.charCodeAt(0)) {
+ } else if (next == {{{ charCode('p') }}}) {
if (currAbsArg === 0) {
argText = '(nil)';
} else {
@@ -2892,27 +2898,27 @@ LibraryManager.library = {
// Convert g/G to f/F or e/E, as per:
// http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html
- if (next == 'g'.charCodeAt(0) || next == 'G'.charCodeAt(0)) {
+ if (next == {{{ charCode('g') }}} || next == {{{ charCode('G') }}}) {
isGeneral = true;
precision = precision || 1;
var exponent = parseInt(currArg.toExponential(effectivePrecision).split('e')[1], 10);
if (precision > exponent && exponent >= -4) {
- next = ((next == 'g'.charCodeAt(0)) ? 'f' : 'F').charCodeAt(0);
+ next = ((next == {{{ charCode('g') }}}) ? 'f' : 'F').charCodeAt(0);
precision -= exponent + 1;
} else {
- next = ((next == 'g'.charCodeAt(0)) ? 'e' : 'E').charCodeAt(0);
+ next = ((next == {{{ charCode('g') }}}) ? 'e' : 'E').charCodeAt(0);
precision--;
}
effectivePrecision = Math.min(precision, 20);
}
- if (next == 'e'.charCodeAt(0) || next == 'E'.charCodeAt(0)) {
+ if (next == {{{ charCode('e') }}} || next == {{{ charCode('E') }}}) {
argText = currArg.toExponential(effectivePrecision);
// Make sure the exponent has at least 2 digits.
if (/[eE][-+]\d$/.test(argText)) {
argText = argText.slice(0, -1) + '0' + argText.slice(-1);
}
- } else if (next == 'f'.charCodeAt(0) || next == 'F'.charCodeAt(0)) {
+ } else if (next == {{{ charCode('f') }}} || next == {{{ charCode('F') }}}) {
argText = currArg.toFixed(effectivePrecision);
}
@@ -2932,7 +2938,7 @@ LibraryManager.library = {
argText = parts[0] + (parts.length > 1 ? 'e' + parts[1] : '');
// Capitalize 'E' if needed.
- if (next == 'E'.charCodeAt(0)) argText = argText.toUpperCase();
+ if (next == {{{ charCode('E') }}}) argText = argText.toUpperCase();
// Add sign.
if (flagAlwaysSigned && currArg >= 0) {
@@ -2954,20 +2960,20 @@ LibraryManager.library = {
}
// Adjust case.
- if (next < 'a'.charCodeAt(0)) argText = argText.toUpperCase();
+ if (next < {{{ charCode('a') }}}) argText = argText.toUpperCase();
// Insert the result into the buffer.
argText.split('').forEach(function(chr) {
ret.push(chr.charCodeAt(0));
});
- } else if (next == 's'.charCodeAt(0)) {
+ } else if (next == {{{ charCode('s') }}}) {
// String.
var arg = getNextArg('i8*') || nullString;
var argLength = _strlen(arg);
if (precisionSet) argLength = Math.min(argLength, precision);
if (!flagLeftAlign) {
while (argLength < width--) {
- ret.push(' '.charCodeAt(0));
+ ret.push({{{ charCode(' ') }}});
}
}
for (var i = 0; i < argLength; i++) {
@@ -2975,21 +2981,21 @@ LibraryManager.library = {
}
if (flagLeftAlign) {
while (argLength < width--) {
- ret.push(' '.charCodeAt(0));
+ ret.push({{{ charCode(' ') }}});
}
}
- } else if (next == 'c'.charCodeAt(0)) {
+ } else if (next == {{{ charCode('c') }}}) {
// Character.
if (flagLeftAlign) ret.push(getNextArg('i8'));
while (--width > 0) {
- ret.push(' '.charCodeAt(0));
+ ret.push({{{ charCode(' ') }}});
}
if (!flagLeftAlign) ret.push(getNextArg('i8'));
- } else if (next == 'n'.charCodeAt(0)) {
+ } else if (next == {{{ charCode('n') }}}) {
// Write the length written so far to the next parameter.
var ptr = getNextArg('i32*');
{{{ makeSetValue('ptr', '0', 'ret.length', 'i32') }}}
- } else if (next == '%'.charCodeAt(0)) {
+ } else if (next == {{{ charCode('%') }}}) {
// Literal percent sign.
ret.push(curr);
} else {
@@ -3138,7 +3144,7 @@ LibraryManager.library = {
var streamObj = FS.streams[stream];
if (streamObj.error || streamObj.eof) return 0;
var byte_;
- for (var i = 0; i < n - 1 && byte_ != '\n'.charCodeAt(0); i++) {
+ for (var i = 0; i < n - 1 && byte_ != {{{ charCode('\n') }}}; i++) {
byte_ = _fgetc(stream);
if (byte_ == -1) {
if (streamObj.error) return 0;
@@ -3244,7 +3250,7 @@ LibraryManager.library = {
if (ret < 0) {
return ret;
} else {
- var newlineRet = _fputc('\n'.charCodeAt(0), stdout);
+ var newlineRet = _fputc({{{ charCode('\n') }}}, stdout);
return (newlineRet < 0) ? -1 : ret + 1;
}
},
@@ -3370,8 +3376,8 @@ LibraryManager.library = {
var stdout = {{{ makeGetValue(makeGlobalUse('_stdout'), '0', 'void*') }}};
if (s) {
_fputs(s, stdout);
- _fputc(':'.charCodeAt(0), stdout);
- _fputc(' '.charCodeAt(0), stdout);
+ _fputc({{{ charCode(':') }}}, stdout);
+ _fputc({{{ charCode(' ') }}}, stdout);
}
var errnum = {{{ makeGetValue('___errno_location()', '0', 'i32') }}};
_puts(_strerror(errnum));
@@ -3669,6 +3675,17 @@ LibraryManager.library = {
abs: 'Math.abs',
labs: 'Math.abs',
+#if USE_TYPED_ARRAYS == 2
+ llabs__deps: [function() { Types.preciseI64MathUsed = 1 }],
+ llabs: function(lo, hi) {
+ i64Math.abs(lo, hi);
+ {{{ makeStructuralReturn([makeGetTempDouble(0, 'i32'), makeGetTempDouble(1, 'i32')]) }}};
+ },
+#else
+ llabs: function(lo, hi) {
+ throw 'unsupported llabs';
+ },
+#endif
exit__deps: ['_exit'],
exit: function(status) {
@@ -3726,93 +3743,6 @@ LibraryManager.library = {
return ret;
},
- strtod__deps: ['isspace', 'isdigit'],
- strtod: function(str, endptr) {
- var origin = str;
-
- // Skip space.
- while (_isspace({{{ makeGetValue('str', 0, 'i8') }}})) str++;
-
- // Check for a plus/minus sign.
- var multiplier = 1;
- if ({{{ makeGetValue('str', 0, 'i8') }}} == '-'.charCodeAt(0)) {
- multiplier = -1;
- str++;
- } else if ({{{ makeGetValue('str', 0, 'i8') }}} == '+'.charCodeAt(0)) {
- str++;
- }
-
- var chr;
- var ret = 0;
-
- // Get whole part.
- var whole = false;
- while(1) {
- chr = {{{ makeGetValue('str', 0, 'i8') }}};
- if (!_isdigit(chr)) break;
- whole = true;
- ret = ret*10 + chr - '0'.charCodeAt(0);
- str++;
- }
-
- // Get fractional part.
- var fraction = false;
- if ({{{ makeGetValue('str', 0, 'i8') }}} == '.'.charCodeAt(0)) {
- str++;
- var mul = 1/10;
- while(1) {
- chr = {{{ makeGetValue('str', 0, 'i8') }}};
- if (!_isdigit(chr)) break;
- fraction = true;
- ret += mul*(chr - '0'.charCodeAt(0));
- mul /= 10;
- str++;
- }
- }
-
- if (!whole && !fraction) {
- if (endptr) {
- {{{ makeSetValue('endptr', 0, 'origin', '*') }}}
- }
- return 0;
- }
-
- // Get exponent part.
- chr = {{{ makeGetValue('str', 0, 'i8') }}};
- if (chr == 'e'.charCodeAt(0) || chr == 'E'.charCodeAt(0)) {
- str++;
- var exponent = 0;
- var expNegative = false;
- chr = {{{ makeGetValue('str', 0, 'i8') }}};
- if (chr == '-'.charCodeAt(0)) {
- expNegative = true;
- str++;
- } else if (chr == '+'.charCodeAt(0)) {
- str++;
- }
- chr = {{{ makeGetValue('str', 0, 'i8') }}};
- while(1) {
- if (!_isdigit(chr)) break;
- exponent = exponent*10 + chr - '0'.charCodeAt(0);
- str++;
- chr = {{{ makeGetValue('str', 0, 'i8') }}};
- }
- if (expNegative) exponent = -exponent;
- ret *= Math.pow(10, exponent);
- }
-
- // Set end pointer.
- if (endptr) {
- {{{ makeSetValue('endptr', 0, 'str', '*') }}}
- }
-
- return ret * multiplier;
- },
- strtod_l: 'strtod', // no locale support yet
- strtold: 'strtod', // XXX add real support for long double
- strtold_l: 'strtold', // no locale support yet
- strtof: 'strtod', // use stdtod to handle strtof
-
_parseInt__deps: ['isspace', '__setErrNo', '$ERRNO_CODES'],
_parseInt: function(str, endptr, base, min, max, bits, unsign) {
// Skip space.
@@ -3820,19 +3750,19 @@ LibraryManager.library = {
// Check for a plus/minus sign.
var multiplier = 1;
- if ({{{ makeGetValue('str', 0, 'i8') }}} == '-'.charCodeAt(0)) {
+ if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('-') }}}) {
multiplier = -1;
str++;
- } else if ({{{ makeGetValue('str', 0, 'i8') }}} == '+'.charCodeAt(0)) {
+ } else if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('+') }}}) {
str++;
}
// Find base.
var finalBase = base;
if (!finalBase) {
- if ({{{ makeGetValue('str', 0, 'i8') }}} == '0'.charCodeAt(0)) {
- if ({{{ makeGetValue('str+1', 0, 'i8') }}} == 'x'.charCodeAt(0) ||
- {{{ makeGetValue('str+1', 0, 'i8') }}} == 'X'.charCodeAt(0)) {
+ if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('0') }}}) {
+ if ({{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('x') }}} ||
+ {{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('X') }}}) {
finalBase = 16;
str += 2;
} else {
@@ -3896,9 +3826,9 @@ LibraryManager.library = {
while (_isspace({{{ makeGetValue('str', 0, 'i8') }}})) str++;
// Check for a plus/minus sign.
- if ({{{ makeGetValue('str', 0, 'i8') }}} == '-'.charCodeAt(0)) {
+ if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('-') }}}) {
str++;
- } else if ({{{ makeGetValue('str', 0, 'i8') }}} == '+'.charCodeAt(0)) {
+ } else if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('+') }}}) {
str++;
}
@@ -3906,9 +3836,9 @@ LibraryManager.library = {
var ok = false;
var finalBase = base;
if (!finalBase) {
- if ({{{ makeGetValue('str', 0, 'i8') }}} == '0'.charCodeAt(0)) {
- if ({{{ makeGetValue('str+1', 0, 'i8') }}} == 'x'.charCodeAt(0) ||
- {{{ makeGetValue('str+1', 0, 'i8') }}} == 'X'.charCodeAt(0)) {
+ if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('0') }}}) {
+ if ({{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('x') }}} ||
+ {{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('X') }}}) {
finalBase = 16;
str += 2;
} else {
@@ -3971,11 +3901,6 @@ LibraryManager.library = {
},
strtoull_l: 'strtoull', // no locale support yet
- atof__deps: ['strtod'],
- atof: function(ptr) {
- return _strtod(ptr, null);
- },
-
atoi__deps: ['strtol'],
atoi: function(ptr) {
return _strtol(ptr, null, 10);
@@ -4235,13 +4160,15 @@ LibraryManager.library = {
memcpy__inline: function (dest, src, num, align) {
var ret = '';
#if ASSERTIONS
+#if ASM_JS == 0
ret += "assert(" + num + " % 1 === 0);"; //, 'memcpy given ' + " + num + " + ' bytes to copy. Problem with quantum=1 corrections perhaps?');";
#endif
+#endif
ret += makeCopyValues(dest, src, num, 'null', null, align);
return ret;
},
- memcpy__asm: 'true',
+ memcpy__asm: true,
memcpy__sig: 'iiii',
memcpy: function (dest, src, num) {
dest = dest|0; src = src|0; num = num|0;
@@ -4314,7 +4241,7 @@ 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) >= {{{ Math.round(2.5*UNROLL_LOOP_MAX) }}}) {
// This is unaligned, but quite large, so work hard to get to aligned settings
value = value & 0xff;
unaligned = ptr & 3;
@@ -4402,14 +4329,18 @@ LibraryManager.library = {
}
},
+ strcpy__asm: true,
+ strcpy__sig: 'iii',
strcpy: function(pdest, psrc) {
+ pdest = pdest|0; psrc = psrc|0;
var i = 0;
do {
- {{{ makeCopyValues('pdest+i', 'psrc+i', 1, 'i8', null, 1) }}};
- i ++;
- } while ({{{ makeGetValue('psrc', 'i-1', 'i8') }}} != 0);
- return pdest;
+ {{{ makeCopyValues('(pdest+i)|0', '(psrc+i)|0', 1, 'i8', null, 1) }}};
+ i = (i+1)|0;
+ } while (({{{ makeGetValue('psrc', 'i-1', 'i8') }}})|0 != 0);
+ return pdest|0;
},
+
stpcpy: function(pdest, psrc) {
var i = 0;
do {
@@ -4419,14 +4350,18 @@ LibraryManager.library = {
return pdest + i - 1;
},
+ strncpy__asm: true,
+ strncpy__sig: 'iiii',
strncpy: function(pdest, psrc, num) {
- var padding = false, curr;
- for (var i = 0; i < num; i++) {
- curr = padding ? 0 : {{{ makeGetValue('psrc', 'i', 'i8') }}};
+ pdest = pdest|0; psrc = psrc|0; num = num|0;
+ var padding = 0, curr = 0, i = 0;
+ while ((i|0) < (num|0)) {
+ curr = padding ? 0 : {{{ makeGetValueAsm('psrc', 'i', 'i8') }}};
{{{ makeSetValue('pdest', 'i', 'curr', 'i8') }}}
- padding = padding || {{{ makeGetValue('psrc', 'i', 'i8') }}} == 0;
+ padding = padding ? 1 : ({{{ makeGetValueAsm('psrc', 'i', 'i8') }}} == 0);
+ i = (i+1)|0;
}
- return pdest;
+ return pdest|0;
},
strlwr__deps:['tolower'],
@@ -4451,15 +4386,18 @@ LibraryManager.library = {
}
},
+ strcat__asm: true,
+ strcat__sig: 'iii',
strcat__deps: ['strlen'],
strcat: function(pdest, psrc) {
- var len = _strlen(pdest);
+ pdest = pdest|0; psrc = psrc|0;
var i = 0;
+ pdest = (pdest + _strlen(pdest))|0;
do {
- {{{ makeCopyValues('pdest+len+i', 'psrc+i', 1, 'i8', null, 1) }}};
- i ++;
- } while ({{{ makeGetValue('psrc', 'i-1', 'i8') }}} != 0);
- return pdest;
+ {{{ makeCopyValues('pdest+i', 'psrc+i', 1, 'i8', null, 1) }}};
+ i = (i+1)|0;
+ } while ({{{ makeGetValueAsm('psrc', 'i-1', 'i8') }}} != 0);
+ return pdest|0;
},
strncat__deps: ['strlen'],
@@ -4485,9 +4423,12 @@ LibraryManager.library = {
// We always assume ASCII locale.
strcoll: 'strcmp',
+ strcasecmp__asm: true,
+ strcasecmp__sig: 'iii',
strcasecmp__deps: ['strncasecmp'],
strcasecmp: function(px, py) {
- return _strncasecmp(px, py, TOTAL_MEMORY);
+ px = px|0; py = py|0;
+ return _strncasecmp(px, py, -1)|0;
},
strncmp: function(px, py, n) {
@@ -4508,26 +4449,29 @@ LibraryManager.library = {
return 0;
},
+ strncasecmp__asm: true,
+ strncasecmp__sig: 'iiii',
strncasecmp__deps: ['tolower'],
strncasecmp: function(px, py, n) {
- var i = 0;
- while (i < n) {
- var x = _tolower({{{ makeGetValue('px', 'i', 'i8', 0, 1) }}});
- var y = _tolower({{{ makeGetValue('py', 'i', 'i8', 0, 1) }}});
- if (x == y && x == 0) return 0;
- if (x == 0) return -1;
- if (y == 0) return 1;
- if (x == y) {
- i ++;
+ px = px|0; py = py|0; n = n|0;
+ var i = 0, x = 0, y = 0;
+ while ((i>>>0) < (n>>>0)) {
+ x = _tolower({{{ makeGetValueAsm('px', 'i', 'i8', 0, 1) }}});
+ y = _tolower({{{ makeGetValueAsm('py', 'i', 'i8', 0, 1) }}});
+ if (((x|0) == (y|0)) & ((x|0) == 0)) return 0;
+ if ((x|0) == 0) return -1;
+ if ((y|0) == 0) return 1;
+ if ((x|0) == (y|0)) {
+ i = (i + 1)|0;
continue;
} else {
- return x > y ? 1 : -1;
+ return ((x>>>0) > (y>>>0) ? 1 : -1)|0;
}
}
return 0;
},
- memcmp__asm: 'true',
+ memcmp__asm: true,
memcmp__sig: 'iiii',
memcmp: function(p1, p2, num) {
p1 = p1|0; p2 = p2|0; num = num|0;
@@ -4729,58 +4673,61 @@ LibraryManager.library = {
return chr & 0x7F;
},
toupper: function(chr) {
- if (chr >= 'a'.charCodeAt(0) && chr <= 'z'.charCodeAt(0)) {
- return chr - 'a'.charCodeAt(0) + 'A'.charCodeAt(0);
+ if (chr >= {{{ charCode('a') }}} && chr <= {{{ charCode('z') }}}) {
+ return chr - {{{ charCode('a') }}} + {{{ charCode('A') }}};
} else {
return chr;
}
},
_toupper: 'toupper',
+
+ tolower__asm: true,
+ tolower__sig: 'ii',
tolower: function(chr) {
- if (chr >= 'A'.charCodeAt(0) && chr <= 'Z'.charCodeAt(0)) {
- return chr - 'A'.charCodeAt(0) + 'a'.charCodeAt(0);
- } else {
- return chr;
- }
+ chr = chr|0;
+ if ((chr|0) < {{{ charCode('A') }}}) return chr|0;
+ if ((chr|0) > {{{ charCode('Z') }}}) return chr|0;
+ return (chr - {{{ charCode('A') }}} + {{{ charCode('a') }}})|0;
},
_tolower: 'tolower',
+
// The following functions are defined as macros in glibc.
islower: function(chr) {
- return chr >= 'a'.charCodeAt(0) && chr <= 'z'.charCodeAt(0);
+ return chr >= {{{ charCode('a') }}} && chr <= {{{ charCode('z') }}};
},
isupper: function(chr) {
- return chr >= 'A'.charCodeAt(0) && chr <= 'Z'.charCodeAt(0);
+ return chr >= {{{ charCode('A') }}} && chr <= {{{ charCode('Z') }}};
},
isalpha: function(chr) {
- return (chr >= 'a'.charCodeAt(0) && chr <= 'z'.charCodeAt(0)) ||
- (chr >= 'A'.charCodeAt(0) && chr <= 'Z'.charCodeAt(0));
+ return (chr >= {{{ charCode('a') }}} && chr <= {{{ charCode('z') }}}) ||
+ (chr >= {{{ charCode('A') }}} && chr <= {{{ charCode('Z') }}});
},
isdigit: function(chr) {
- return chr >= '0'.charCodeAt(0) && chr <= '9'.charCodeAt(0);
+ return chr >= {{{ charCode('0') }}} && chr <= {{{ charCode('9') }}};
},
isdigit_l: 'isdigit', // no locale support yet
isxdigit: function(chr) {
- return (chr >= '0'.charCodeAt(0) && chr <= '9'.charCodeAt(0)) ||
- (chr >= 'a'.charCodeAt(0) && chr <= 'f'.charCodeAt(0)) ||
- (chr >= 'A'.charCodeAt(0) && chr <= 'F'.charCodeAt(0));
+ return (chr >= {{{ charCode('0') }}} && chr <= {{{ charCode('9') }}}) ||
+ (chr >= {{{ charCode('a') }}} && chr <= {{{ charCode('f') }}}) ||
+ (chr >= {{{ charCode('A') }}} && chr <= {{{ charCode('F') }}});
},
isxdigit_l: 'isxdigit', // no locale support yet
isalnum: function(chr) {
- return (chr >= '0'.charCodeAt(0) && chr <= '9'.charCodeAt(0)) ||
- (chr >= 'a'.charCodeAt(0) && chr <= 'z'.charCodeAt(0)) ||
- (chr >= 'A'.charCodeAt(0) && chr <= 'Z'.charCodeAt(0));
+ return (chr >= {{{ charCode('0') }}} && chr <= {{{ charCode('9') }}}) ||
+ (chr >= {{{ charCode('a') }}} && chr <= {{{ charCode('z') }}}) ||
+ (chr >= {{{ charCode('A') }}} && chr <= {{{ charCode('Z') }}});
},
ispunct: function(chr) {
- return (chr >= '!'.charCodeAt(0) && chr <= '/'.charCodeAt(0)) ||
- (chr >= ':'.charCodeAt(0) && chr <= '@'.charCodeAt(0)) ||
- (chr >= '['.charCodeAt(0) && chr <= '`'.charCodeAt(0)) ||
- (chr >= '{'.charCodeAt(0) && chr <= '~'.charCodeAt(0));
+ return (chr >= {{{ charCode('!') }}} && chr <= {{{ charCode('/') }}}) ||
+ (chr >= {{{ charCode(':') }}} && chr <= {{{ charCode('@') }}}) ||
+ (chr >= {{{ charCode('[') }}} && chr <= {{{ charCode('`') }}}) ||
+ (chr >= {{{ charCode('{') }}} && chr <= {{{ charCode('~') }}});
},
isspace: function(chr) {
return chr in { 32: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0 };
},
isblank: function(chr) {
- return chr == ' '.charCodeAt(0) || chr == '\t'.charCodeAt(0);
+ return chr == {{{ charCode(' ') }}} || chr == {{{ charCode('\t') }}};
},
iscntrl: function(chr) {
return (0 <= chr && chr <= 0x1F) || chr === 0x7F;
@@ -4976,6 +4923,20 @@ LibraryManager.library = {
#endif
},
+ llvm_ctpop_i32: function(x) {
+ var ret = 0;
+ while (x) {
+ if (x&1) ret++;
+ x >>= 1;
+ }
+ return ret;
+ },
+
+ llvm_ctpop_i64__deps: ['llvm_ctpop_i32'],
+ llvm_ctpop_i64: function(l, h) {
+ return _llvm_ctpop_i32(l) + _llvm_ctpop_i32(h);
+ },
+
llvm_trap: function() {
throw 'trap! ' + new Error().stack;
},
@@ -5270,13 +5231,6 @@ LibraryManager.library = {
{{{ 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);
- {{{ makeStructuralReturn([makeGetTempDouble(0, 'i32'), makeGetTempDouble(1, 'i32'), '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.multiply(xl, xh, yl, yh);
@@ -5506,6 +5460,14 @@ LibraryManager.library = {
return -a;
},
copysignf: 'copysign',
+ __signbit__deps: ['copysign'],
+ __signbit: function(x) {
+ // We implement using copysign so that we get support
+ // for negative zero (once copysign supports that).
+ return _copysign(1.0, x) < 0;
+ },
+ __signbitf: '__signbit',
+ __signbitd: '__signbit',
hypot: function(a, b) {
return Math.sqrt(a*a + b*b);
},
@@ -6064,6 +6026,15 @@ LibraryManager.library = {
__timespec_struct_layout: Runtime.generateStructInfo([
['i32', 'tv_sec'],
['i32', 'tv_nsec']]),
+ nanosleep__deps: ['usleep', '__timespec_struct_layout'],
+ nanosleep: function(rqtp, rmtp) {
+ // int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
+ var seconds = {{{ makeGetValue('rqtp', '___timespec_struct_layout.tv_sec', 'i32') }}};
+ var nanoseconds = {{{ makeGetValue('rqtp', '___timespec_struct_layout.tv_nsec', 'i32') }}};
+ {{{ makeSetValue('rmtp', '___timespec_struct_layout.tv_sec', '0', 'i32') }}}
+ {{{ makeSetValue('rmtp', '___timespec_struct_layout.tv_nsec', '0', 'i32') }}}
+ return _usleep((seconds * 1e6) + (nanoseconds / 1000));
+ },
// TODO: Implement these for real.
clock_gettime__deps: ['__timespec_struct_layout'],
clock_gettime: function(clk_id, tp) {
@@ -6170,7 +6141,7 @@ LibraryManager.library = {
setjmp__inline: function(env) {
// Save the label
- return '(tempInt = setjmpId++, mySetjmpIds[tempInt] = 1, setjmpLabels[tempInt] = label,' + makeSetValue(env, '0', 'tempInt', 'i32') + ', 0)';
+ return '(tempInt = setjmpId++, mySetjmpIds[tempInt] = 1, setjmpLabels[tempInt] = label,' + makeSetValue(env, '0', 'tempInt', 'i32', undefined, undefined, undefined, undefined, ',') + ', 0)';
},
longjmp: function(env, value) {
@@ -6693,6 +6664,13 @@ LibraryManager.library = {
},
// ==========================================================================
+ // sched.h (stubs only - no thread support yet!)
+ // ==========================================================================
+ sched_yield: function() {
+ return 0;
+ },
+
+ // ==========================================================================
// pthread.h (stubs for mutexes only - no thread support yet!)
// ==========================================================================
@@ -6708,8 +6686,15 @@ LibraryManager.library = {
},
pthread_cond_init: function() {},
pthread_cond_destroy: function() {},
- pthread_cond_broadcast: function() {},
- pthread_cond_wait: function() {},
+ pthread_cond_broadcast: function() {
+ return 0;
+ },
+ pthread_cond_wait: function() {
+ return 0;
+ },
+ pthread_cond_timedwait: function() {
+ return 0;
+ },
pthread_self: function() {
//FIXME: assumes only a single thread
return 0;
@@ -7385,6 +7370,81 @@ LibraryManager.library = {
Module.print(intArrayToString(__formatString(_emscripten_jcache_printf_.buffer, varargs + i*4)).replace('\\n', ''));
Runtime.stackAlloc(-4*i); // free up the stack space we know is ok to free
},
+
+ //============================
+ // i64 math
+ //============================
+
+ i64Add__asm: true,
+ i64Add__sig: 'iiiii',
+ i64Add: function(a, b, c, d) {
+ /*
+ x = a + b*2^32
+ y = c + d*2^32
+ result = l + h*2^32
+ */
+ a = a|0; b = b|0; c = c|0; d = d|0;
+ var l = 0, h = 0;
+ l = (a + c)>>>0;
+ h = (b + d)>>>0;
+ if ((l>>>0) < (a>>>0)) { // iff we overflowed
+ h = (h+1)>>>0;
+ }
+ {{{ makeStructuralReturn(['l|0', 'h'], true) }}};
+ },
+ llvm_uadd_with_overflow_i64__asm: true,
+ llvm_uadd_with_overflow_i64__sig: 'iiiii',
+ llvm_uadd_with_overflow_i64: function(a, b, c, d) {
+ a = a|0; b = b|0; c = c|0; d = d|0;
+ var l = 0, h = 0, overflow = 0;
+ l = (a + c)>>>0;
+ h = (b + d)>>>0;
+ if ((l>>>0) < (a>>>0)) { // iff we overflowed
+ h = (h+1)>>>0;
+ overflow = 1;
+ }
+ {{{ makeStructuralReturn(['l|0', 'h', 'overflow'], true) }}};
+ },
+
+ bitshift64Shl__asm: true,
+ bitshift64Shl__sig: 'iiii',
+ bitshift64Shl: function(low, high, bits) {
+ low = low|0; high = high|0; bits = bits|0;
+ var ander = 0;
+ if ((bits|0) < 32) {
+ ander = ((1 << bits) - 1)|0;
+ tempRet0 = (high << bits) | ((low&(ander << (32 - bits))) >>> (32 - bits));
+ return low << bits;
+ }
+ tempRet0 = low << (bits - 32);
+ return 0;
+ },
+ bitshift64Ashr__asm: true,
+ bitshift64Ashr__sig: 'iiii',
+ bitshift64Ashr: function(low, high, bits) {
+ low = low|0; high = high|0; bits = bits|0;
+ var ander = 0;
+ if ((bits|0) < 32) {
+ ander = ((1 << bits) - 1)|0;
+ tempRet0 = high >> bits;
+ return (low >>> bits) | ((high&ander) << (32 - bits));
+ }
+ tempRet0 = (high|0) < 0 ? -1 : 0;
+ return (high >> (bits - 32))|0;
+ },
+ bitshift64Lshr__asm: true,
+ bitshift64Lshr__sig: 'iiii',
+ bitshift64Lshr: function(low, high, bits) {
+ low = low|0; high = high|0; bits = bits|0;