summaryrefslogtreecommitdiff
path: root/src/library.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/library.js')
-rw-r--r--src/library.js129
1 files changed, 107 insertions, 22 deletions
diff --git a/src/library.js b/src/library.js
index c8205d2b..1ba4f2fa 100644
--- a/src/library.js
+++ b/src/library.js
@@ -573,7 +573,7 @@ LibraryManager.library = {
eof: false,
ungotten: []
};
- assert(Math.max(_stdin, _stdout, _stderr) < 128); // make sure these are low, we flatten arrays with these
+ assert(Math.max(_stdin, _stdout, _stderr) < 1024); // 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*') }}};
@@ -4913,16 +4913,20 @@ LibraryManager.library = {
}
return 8;
}
- return 'var ctlz_i8 = [' + range(256).map(function(x) { return ctlz(x) }).join(',') + '];';
+ return 'var ctlz_i8 = allocate([' + range(256).map(function(x) { return ctlz(x) }).join(',') + '], "i8", ALLOC_STACK);';
}],
+ llvm_ctlz_i32__asm: true,
+ llvm_ctlz_i32__sig: 'ii',
llvm_ctlz_i32: function(x) {
- var ret = ctlz_i8[x >>> 24];
- if (ret < 8) return ret;
- var ret = ctlz_i8[(x >> 16)&0xff];
- if (ret < 8) return ret + 8;
- var ret = ctlz_i8[(x >> 8)&0xff];
- if (ret < 8) return ret + 16;
- return ctlz_i8[x&0xff] + 24;
+ x = x|0;
+ var ret = 0;
+ ret = {{{ makeGetValueAsm('ctlz_i8', 'x >>> 24', 'i8') }}};
+ if ((ret|0) < 8) return ret|0;
+ var ret = {{{ makeGetValueAsm('ctlz_i8', '(x >> 16)&0xff', 'i8') }}};
+ if ((ret|0) < 8) return (ret + 8)|0;
+ var ret = {{{ makeGetValueAsm('ctlz_i8', '(x >> 8)&0xff', 'i8') }}};
+ if ((ret|0) < 8) return (ret + 16)|0;
+ return ({{{ makeGetValueAsm('ctlz_i8', 'x&0xff', 'i8') }}} + 24)|0;
},
llvm_ctlz_i64__deps: ['llvm_ctlz_i32'],
@@ -4945,16 +4949,20 @@ LibraryManager.library = {
}
return 8;
}
- return 'var cttz_i8 = [' + range(256).map(function(x) { return cttz(x) }).join(',') + '];';
+ return 'var cttz_i8 = allocate([' + range(256).map(function(x) { return cttz(x) }).join(',') + '], "i8", ALLOC_STACK);';
}],
+ llvm_cttz_i32__asm: true,
+ llvm_cttz_i32__sig: 'ii',
llvm_cttz_i32: function(x) {
- var ret = cttz_i8[x & 0xff];
- if (ret < 8) return ret;
- var ret = cttz_i8[(x >> 8)&0xff];
- if (ret < 8) return ret + 8;
- var ret = cttz_i8[(x >> 16)&0xff];
- if (ret < 8) return ret + 16;
- return cttz_i8[x >>> 24] + 24;
+ x = x|0;
+ var ret = 0;
+ ret = {{{ makeGetValueAsm('cttz_i8', 'x & 0xff', 'i8') }}};
+ if ((ret|0) < 8) return ret|0;
+ var ret = {{{ makeGetValueAsm('cttz_i8', '(x >> 8)&0xff', 'i8') }}};
+ if ((ret|0) < 8) return (ret + 8)|0;
+ var ret = {{{ makeGetValueAsm('cttz_i8', '(x >> 16)&0xff', 'i8') }}};
+ if ((ret|0) < 8) return (ret + 16)|0;
+ return ({{{ makeGetValueAsm('cttz_i8', 'x >>> 24', 'i8') }}} + 24)|0;
},
llvm_cttz_i64__deps: ['llvm_cttz_i32'],
@@ -5296,9 +5304,11 @@ LibraryManager.library = {
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);
- {{{ makeStructuralReturn([makeGetTempDouble(0, 'i32'), makeGetTempDouble(1, 'i32'), '0']) }}};
- // XXX Need to hack support for second param in long.js
+#if ASSERTIONS
+ Runtime.warnOnce('no overflow support in llvm_umul_with_overflow_i64');
+#endif
+ var low = ___muldi3(xl, xh, yl, yh);
+ {{{ makeStructuralReturn(['low', 'tempRet0', '0']) }}};
},
llvm_stacksave: function() {
@@ -6207,13 +6217,74 @@ LibraryManager.library = {
// related functionality so the slowdown is more limited.
// ==========================================================================
+ saveSetjmp__asm: true,
+ saveSetjmp__sig: 'iii',
+ saveSetjmp: function(env, label, table) {
+ // Not particularly fast: slow table lookup of setjmpId to label. But setjmp
+ // prevents relooping anyhow, so slowness is to be expected. And typical case
+ // is 1 setjmp per invocation, or less.
+ env = env|0;
+ label = label|0;
+ table = table|0;
+ var i = 0;
+#if ASSERTIONS
+ if ((label|0) == 0) abort(121);
+#endif
+ setjmpId = (setjmpId+1)|0;
+ {{{ makeSetValueAsm('env', '0', 'setjmpId', 'i32') }}};
+ while ((i|0) < {{{ MAX_SETJMPS }}}) {
+ if ({{{ makeGetValueAsm('table', 'i*4', 'i32') }}} == 0) {
+ {{{ makeSetValueAsm('table', 'i*4', 'setjmpId', 'i32') }}};
+ {{{ makeSetValueAsm('table', 'i*4+4', 'label', 'i32') }}};
+ // prepare next slot
+ {{{ makeSetValueAsm('table', 'i*4+8', '0', 'i32') }}};
+ return 0;
+ }
+ i = (i+2)|0;
+ }
+ abort(987); // if you hit this, adjust MAX_SETJMPS
+ return 0;
+ },
+
+ testSetjmp__asm: true,
+ testSetjmp__sig: 'iii',
+ testSetjmp: function(id, table) {
+ id = id|0;
+ table = table|0;
+ var i = 0, curr = 0;
+ while ((i|0) < {{{ MAX_SETJMPS }}}) {
+ curr = {{{ makeGetValueAsm('table', 'i*4', 'i32') }}};
+ if ((curr|0) == 0) break;
+ if ((curr|0) == (id|0)) {
+ return {{{ makeGetValueAsm('table', 'i*4+4', 'i32') }}};
+ }
+ i = (i+2)|0;
+ }
+ return 0;
+ },
+
+#if ASM_JS
+ setjmp__deps: ['saveSetjmp', 'testSetjmp'],
+#endif
setjmp__inline: function(env) {
// Save the label
+#if ASM_JS
+ return '_saveSetjmp(' + env + ', label, setjmpTable)';
+#else
return '(tempInt = setjmpId++, mySetjmpIds[tempInt] = 1, setjmpLabels[tempInt] = label,' + makeSetValue(env, '0', 'tempInt', 'i32', undefined, undefined, undefined, undefined, ',') + ', 0)';
+#endif
},
+#if ASM_JS
+ longjmp__deps: ['saveSetjmp', 'testSetjmp'],
+#endif
longjmp: function(env, value) {
+#if ASM_JS
+ asm.setThrew(env, value || 1);
+ throw 'longjmp';
+#else
throw { longjmp: true, id: {{{ makeGetValue('env', '0', 'i32') }}}, value: value || 1 };
+#endif
},
// ==========================================================================
@@ -7492,13 +7563,27 @@ LibraryManager.library = {
var l = 0, h = 0, overflow = 0;
l = (a + c)>>>0;
h = (b + d)>>>0;
- if ((l>>>0) < (a>>>0)) { // iff we overflowed
+ if ((h>>>0) < (b>>>0)) overflow = 1;
+ if ((l>>>0) < (a>>>0)) {
h = (h+1)>>>0;
- overflow = 1;
+ if ((h>>>0) == 0) overflow = 1; // two possibilities to overflow here
}
{{{ makeStructuralReturn(['l|0', 'h', 'overflow'], true) }}};
},
+ i64Subtract__asm: true,
+ i64Subtract__sig: 'iiiii',
+ i64Subtract: function(a, b, c, d) {
+ 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) }}};
+ },
+
bitshift64Shl__asm: true,
bitshift64Shl__sig: 'iiii',
bitshift64Shl: function(low, high, bits) {