aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analyzer.js60
-rw-r--r--src/library.js12
-rw-r--r--src/parseTools.js24
-rw-r--r--src/runtime.js10
-rw-r--r--src/utility.js2
5 files changed, 79 insertions, 29 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index e1f2f6c1..729d4607 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -169,6 +169,15 @@ function analyzer(data, sidePass) {
item[slot] = { intertype: 'value', ident: tempIdent, type: item[slot].type };
return i+1;
}
+ function removeAndAdd(lines, i, toAdd) {
+ var item = lines[i];
+ var interp = getInterp(lines, i, toAdd.length);
+ for (var k = 0; k < toAdd.length; k++) {
+ toAdd[k].lineNum = item.lineNum + (k*interp);
+ }
+ Array.prototype.splice.apply(lines, [i, 1].concat(toAdd));
+ return toAdd.length;
+ }
// Assuming we will replace the item at line i, with num items, returns
// the right factor to multiply line numbers by so that they fit in between
// the removed line and the line after it
@@ -184,16 +193,15 @@ function analyzer(data, sidePass) {
if (item.intertype == 'store') {
if (isIllegalType(item.valueType)) {
dprint('legalizer', 'Legalizing store at line ' + item.lineNum);
+ var toAdd = [];
bits = getBits(item.valueType);
i = unfold(label.lines, i, item, 'value');
- var interp = getInterp(label.lines, i, Math.ceil(bits/32));
- label.lines.splice(i, 1);
var elements;
elements = getLegalVars(item.value.ident, bits);
var j = 0;
elements.forEach(function(element) {
var tempVar = '$st$' + i + '$' + j;
- label.lines.splice(i+j*2, 0, {
+ toAdd.push({
intertype: 'getelementptr',
assignTo: tempVar,
ident: item.pointer.ident,
@@ -203,10 +211,9 @@ function analyzer(data, sidePass) {
{ intertype: 'value', ident: '0', type: 'i32' },
{ intertype: 'value', ident: j.toString(), type: 'i32' }
],
- lineNum: item.lineNum + (j*interp)
});
var actualSizeType = 'i' + element.bits; // The last one may be smaller than 32 bits
- label.lines.splice(i+j*2+1, 0, {
+ toAdd.push({
intertype: 'store',
valueType: actualSizeType,
value: { intertype: 'value', ident: element.ident, type: actualSizeType },
@@ -214,12 +221,11 @@ function analyzer(data, sidePass) {
ident: tempVar,
pointerType: actualSizeType + '*',
align: item.align,
- lineNum: item.lineNum + ((j+0.5)*interp)
});
j++;
});
Types.needAnalysis['[0 x i32]'] = 0;
- i += j*2;
+ i += removeAndAdd(label.lines, i, toAdd);
continue;
}
} else if (item.assignTo) {
@@ -267,6 +273,38 @@ function analyzer(data, sidePass) {
i += j*2;
continue;
}
+ break;
+ }
+ case 'phi': {
+ if (isIllegalType(value.type)) {
+ dprint('legalizer', 'Legalizing phi at line ' + item.lineNum);
+ bits = getBits(value.type);
+ var toAdd = [];
+ var elements = getLegalVars(item.assignTo, bits);
+ var j = 0;
+ elements.forEach(function(element) {
+ toAdd.push({
+ intertype: 'phi',
+ assignTo: element.ident,
+ type: 'i' + element.bits,
+ params: value.params.map(function(param) {
+ return {
+ intertype: 'phiparam',
+ label: param.label,
+ value: { // TODO: unfolding
+ intertype: 'value',
+ ident: param.value.ident + '$' + j,
+ type: 'i' + element.bits,
+ }
+ };
+ })
+ });
+ j++;
+ });
+ i += removeAndAdd(label.lines, i, toAdd);
+ continue;
+ }
+ break;
}
case 'mathop': {
if (isIllegalType(value.type)) {
@@ -412,14 +450,10 @@ function analyzer(data, sidePass) {
legalValue.assignTo = item.assignTo;
toAdd.push(legalValue);
}
- var interp = getInterp(label.lines, i, toAdd.length);
- for (var k = 0; k < toAdd.length; k++) {
- toAdd[k].lineNum = item.lineNum + (k*interp);
- }
- Array.prototype.splice.apply(label.lines, [i, 1].concat(toAdd));
- i += toAdd.length;
+ i += removeAndAdd(label.lines, i, toAdd);
continue;
}
+ break;
}
}
}
diff --git a/src/library.js b/src/library.js
index 6385507c..86c499a7 100644
--- a/src/library.js
+++ b/src/library.js
@@ -4392,7 +4392,7 @@ LibraryManager.library = {
__cxa_free_exception: function(ptr) {
return _free(ptr);
},
- __cxa_throw__deps: ['llvm_eh_exception'],
+ __cxa_throw__deps: ['llvm_eh_exception', '_ZSt18uncaught_exceptionv'],
__cxa_throw: function(ptr, type, destructor) {
#if EXCEPTION_DEBUG
print('Compiled code throwing an exception, ' + [ptr,type,destructor] + ', at ' + new Error().stack);
@@ -4400,6 +4400,11 @@ LibraryManager.library = {
{{{ makeSetValue('_llvm_eh_exception.buf', '0', 'ptr', 'void*') }}}
{{{ makeSetValue('_llvm_eh_exception.buf', QUANTUM_SIZE, 'type', 'void*') }}}
{{{ makeSetValue('_llvm_eh_exception.buf', 2 * QUANTUM_SIZE, 'destructor', 'void*') }}}
+ if (!("uncaught_exception" in __ZSt18uncaught_exceptionv)) {
+ __ZSt18uncaught_exceptionv.uncaught_exception = 1;
+ } else {
+ __ZSt18uncaught_exceptionv.uncaught_exception++;
+ }
throw ptr;
},
__cxa_rethrow__deps: ['llvm_eh_exception', '__cxa_end_catch'],
@@ -4425,7 +4430,9 @@ LibraryManager.library = {
_Unwind_Resume_or_Rethrow: function(ptr) {
throw ptr;
},
+ __cxa_begin_catch__deps: ['_ZSt18uncaught_exceptionv'],
__cxa_begin_catch: function(ptr) {
+ __ZSt18uncaught_exceptionv.uncaught_exception--;
return ptr;
},
__cxa_end_catch__deps: ['llvm_eh_exception', '__cxa_free_exception'],
@@ -4455,6 +4462,9 @@ LibraryManager.library = {
__cxa_get_exception_ptr: function(ptr) {
return ptr;
},
+ _ZSt18uncaught_exceptionv: function() { // std::uncaught_exception()
+ return !!__ZSt18uncaught_exceptionv.uncaught_exception;
+ },
__cxa_call_unexpected: function(exception) {
ABORT = true;
diff --git a/src/parseTools.js b/src/parseTools.js
index a5752e67..3cc17cc4 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -962,32 +962,32 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore, align, noSafe,
if (DOUBLE_MODE == 1 && USE_TYPED_ARRAYS == 2 && type == 'double') {
return '(tempDoubleF64[0]=' + value + ',' +
- makeSetValue(ptr, pos, 'tempDoubleI32[0]', 'i32', noNeedFirst, ignore, align) + ',' +
- makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'tempDoubleI32[1]', 'i32', noNeedFirst, ignore, align) + ')';
+ makeSetValue(ptr, pos, 'tempDoubleI32[0]', 'i32', noNeedFirst, ignore, align, noSafe, ',') + ',' +
+ makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'tempDoubleI32[1]', 'i32', noNeedFirst, ignore, align, noSafe, ',') + ')';
}
- if (USE_TYPED_ARRAYS == 2 && align) {
- // Alignment is important here. May need to split this up
+ var needSplitting = isIntImplemented(type) && !isPowerOfTwo(getBits(type)); // an unnatural type like i24
+ if (USE_TYPED_ARRAYS == 2 && (align || needSplitting)) {
+ // Alignment is important here, or we need to split this up for other reasons.
var bytes = Runtime.getNativeTypeSize(type);
- if (bytes > align) {
+ if (bytes > align || needSplitting) {
var ret = '';
if (isIntImplemented(type)) {
if (bytes == 4 && align == 2) {
// Special case that we can optimize
ret += 'tempBigInt=' + value + sep;
ret += makeSetValue(ptr, pos, 'tempBigInt&0xffff', 'i16', noNeedFirst, ignore, 2) + sep;
- ret += makeSetValue(ptr, getFastValue(pos, '+', 2), 'tempBigInt>>16', 'i16', noNeedFirst, ignore, 2) + sep;
- } else if (bytes <= 4) {
+ ret += makeSetValue(ptr, getFastValue(pos, '+', 2), 'tempBigInt>>16', 'i16', noNeedFirst, ignore, 2);
+ } else if (bytes != 8) {
ret += 'tempBigInt=' + value + sep;
for (var i = 0; i < bytes; i++) {
- ret += makeSetValue(ptr, getFastValue(pos, '+', i), 'tempBigInt&0xff', 'i8', noNeedFirst, ignore, 1) + sep;
- if (i < bytes-1) ret += 'tempBigInt>>=8' + sep;
+ ret += makeSetValue(ptr, getFastValue(pos, '+', i), 'tempBigInt&0xff', 'i8', noNeedFirst, ignore, 1);
+ if (i < bytes-1) ret += sep + 'tempBigInt>>=8' + sep;
}
- } else {
- assert(bytes == 8);
+ } else { // bytes == 8, specific optimization
ret += 'tempPair=' + ensureI64_1(value) + sep;
ret += makeSetValue(ptr, pos, 'tempPair[0]', 'i32', noNeedFirst, ignore, align) + sep;
- ret += makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'tempPair[1]', 'i32', noNeedFirst, ignore, align) + sep;
+ ret += makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'tempPair[1]', 'i32', noNeedFirst, ignore, align);
}
} else {
ret += makeSetValue('tempDoublePtr', 0, value, type, noNeedFirst, ignore, 8) + sep;
diff --git a/src/runtime.js b/src/runtime.js
index 190260e6..b5663045 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -185,8 +185,14 @@ var Runtime = {
"%float": 4,
"%double": 8
}['%'+type]; // add '%' since float and double confuse Closure compiler as keys, and also spidermonkey as a compiler will remove 's from '_i8' etc
- if (!size && type[type.length-1] == '*') {
- size = Runtime.QUANTUM_SIZE; // A pointer
+ if (!size) {
+ if (type[type.length-1] == '*') {
+ size = Runtime.QUANTUM_SIZE; // A pointer
+ } else if (type[0] == 'i') {
+ var bits = parseInt(type.substr(1));
+ assert(bits % 8 == 0);
+ size = bits/8;
+ }
}
return size;
},
diff --git a/src/utility.js b/src/utility.js
index 5ddccfd4..31eff100 100644
--- a/src/utility.js
+++ b/src/utility.js
@@ -21,7 +21,7 @@ function dump(item) {
ret.push(i + ': [?]');
}
}
- return lineify(ret.join(', '));
+ return ret.join(',\n');
}
}