aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analyzer.js14
-rw-r--r--src/intertyper.js8
-rw-r--r--src/jsifier.js10
-rw-r--r--src/parseTools.js12
-rw-r--r--src/preamble.js6
-rw-r--r--src/runtime.js6
-rw-r--r--src/settings.js8
7 files changed, 51 insertions, 13 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index b7660281..96e6297b 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -375,10 +375,8 @@ function analyzer(data) {
if (USE_TYPED_ARRAYS !== 2) return;
function seekIdent(item, obj) {
-//if (item.intertype === 'value') print('seeeeeeek ' + dump(item));
if (item.ident === obj.ident) {
obj.found++;
-//print('zz FOUNDZEY');
}
}
@@ -395,14 +393,18 @@ function analyzer(data) {
item.functions.forEach(function(func) {
func.lines.forEach(function(line, i) {
if (line.intertype === 'assign' && line.value.intertype === 'load') {
- var total = func.variables[line.ident].uses;
+ var data = func.variables[line.ident]
+ if (data.type === 'i1') {
+ line.value.unsigned = true;
+ return;
+ }
+
+ var total = data.uses;
if (total === 0) return;
var obj = { ident: line.ident, found: 0, unsigned: 0, signed: 0, total: total };
-//print('zz SIGNALYZE ' + line.lineNum + ' : ' + dump(obj));
// in loops with phis, we can also be used *before* we are defined
var j = i-1, k = i+1;
while(1) {
-//print(' ' + [j >= 0 ? func.lines[j].lineNum : null, k < func.lines.length ? func.lines[k].lineNum : null, obj.found, obj.total]);
assert(j >= 0 || k < func.lines.length, 'Signalyzer ran out of space to look for sign indications for line ' + line.lineNum);
if (j >= 0 && walkInterdata(func.lines[j], seekIdent, seekMathop, obj)) break;
if (k < func.lines.length && walkInterdata(func.lines[k], seekIdent, seekMathop, obj)) break;
@@ -410,7 +412,7 @@ function analyzer(data) {
j -= 1;
k += 1;
}
-//print('zz signz: ' + dump(obj));
+
// unsigned+signed might be < total, since the same ident can appear multiple times in the same mathop.
// found can actually be > total, since we currently have the same ident in a GEP (see cubescript test)
// in the GEP item, and a child item (we have the ident copied onto the GEP item as a convenience).
diff --git a/src/intertyper.js b/src/intertyper.js
index 95b1fcd3..232025cb 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -632,11 +632,17 @@ function intertyper(data, parseFunctions, baseLineNum) {
}
});
// 'alloca'
+ var allocaPossibleVars = ['allocatedNum'];
substrate.addActor('Alloca', {
processItem: function(item) {
item.intertype = 'alloca';
item.allocatedType = item.tokens[1].text;
- item.allocatedNum = (item.tokens.length > 3 && Runtime.isNumberType(item.tokens[3].text)) ? toNiceIdent(item.tokens[4].text) : 1;
+ if (item.tokens.length > 3 && Runtime.isNumberType(item.tokens[3].text)) {
+ item.allocatedNum = toNiceIdent(item.tokens[4].text);
+ item.possibleVars = allocaPossibleVars;
+ } else {
+ item.allocatedNum = 1;
+ }
item.type = addPointing(item.tokens[1].text); // type of pointer we will get
Types.needAnalysis[item.type] = 0;
item.type2 = item.tokens[1].text; // value we will create, and get a pointer to
diff --git a/src/jsifier.js b/src/jsifier.js
index c6f73d50..3da296f1 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -685,12 +685,15 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
makeFuncLineActor('invoke', function(item) {
// Wrapping in a function lets us easily return values if we are
// in an assignment
+ var call_ = makeFunctionCall(item.ident, item.params, item.funcData);
+ var branch = makeBranch(item.toLabel, item.currLabelId);
+ if (DISABLE_EXCEPTIONS) return call_ + '; ' + branch;
var ret = '(function() { try { __THREW__ = false; return '
- + makeFunctionCall(item.ident, item.params, item.funcData) + ' '
+ + call_ + ' '
+ '} catch(e) { '
+ 'if (ABORT) throw e; __THREW__ = true; '
+ (EXCEPTION_DEBUG ? 'print("Exception: " + e + ", currently at: " + (new Error().stack)); ' : '')
- + 'return null } })(); if (!__THREW__) { ' + makeBranch(item.toLabel, item.currLabelId)
+ + 'return null } })(); if (!__THREW__) { ' + branch
+ ' } else { ' + makeBranch(item.unwindLabel, item.currLabelId) + ' }';
return ret;
});
@@ -793,7 +796,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
return makeFunctionCall(item.ident, item.params, item.funcData) + (item.standalone ? ';' : '');
});
- makeFuncLineActor('unreachable', function(item) { return 'throw "Reached an unreachable! Original .ll line: ' + item.lineNum + '";' });
+ makeFuncLineActor('unreachable', function(item) { return 'throw "Reached an unreachable!"' }); // Original .ll line: ' + item.lineNum + '";' });
// Final combiner
@@ -837,6 +840,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
if (RUNTIME_TYPE_INFO) {
Types.cleanForRuntime();
print('Runtime.typeInfo = ' + JSON.stringify(Types.types));
+ print('Runtime.structMetadata = ' + JSON.stringify(Types.structMetadata));
}
generated.forEach(function(item) { print(indentify(item.JS || '', 2)); });
print(Functions.generateIndexing());
diff --git a/src/parseTools.js b/src/parseTools.js
index 91956cad..6eb95593 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -730,6 +730,11 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore) {
if (isStructType(type)) {
var typeData = Types.types[type];
var ret = [];
+ // We can receive either an object - an object literal that was in the .ll - or a string,
+ // which is the ident of an aggregate struct
+ if (typeof value === 'string') {
+ value = range(typeData.fields.length).map(function(i) { return value + '.f' + i });
+ }
for (var i = 0; i < typeData.fields.length; i++) {
ret.push(makeSetValue(ptr, pos + typeData.flatIndexes[i], value[i], typeData.fields[i], noNeedFirst));
}
@@ -1278,6 +1283,13 @@ function walkInterdata(item, pre, post, obj) {
if (walkInterdata(item.params[i], pre, post, obj)) return true;
}
}
+ if (item.possibleVars) { // other attributes that might contain interesting data; here, variables
+ var box = { intertype: 'value', ident: '' };
+ for (i = 0; i <= item.possibleVars.length; i++) {
+ box.ident = item[item.possibleVars[i]];
+ if (walkInterdata(box, pre, post, obj)) return true;
+ }
+ }
return post(item, originalObj, obj);
}
diff --git a/src/preamble.js b/src/preamble.js
index 8feb43e9..0d802409 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -320,6 +320,7 @@ function setValue(ptr, value, type) {
default: abort('invalid type for setValue: ' + type);
}
}
+this['setValue'] = setValue;
// Parallel to setValue.
@@ -337,6 +338,7 @@ function getValue(ptr, type) {
}
return null;
}
+this['getValue'] = getValue;
// Allocates memory for some data and initializes it properly.
@@ -446,6 +448,10 @@ if (HAS_TYPED_ARRAYS) {
HEAPU16 = new Uint16Array(buffer);
HEAPU32 = new Uint32Array(buffer);
HEAPF32 = new Float32Array(buffer);
+
+ // Endianness check (note: assumes compiler arch was little-endian)
+ HEAP32[0] = 255;
+ assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system');
#endif
} else
#endif
diff --git a/src/runtime.js b/src/runtime.js
index ad3c973d..abeb0d2a 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -183,11 +183,11 @@ Runtime = {
var type, alignment;
if (typeName) {
offset = offset || 0;
- type = typeof Types === 'undefined' ? Runtime.typeInfo[typeName] : Types.types[typeName];
+ type = (typeof Types === 'undefined' ? Runtime.typeInfo : Types.types)[typeName];
if (!type) return null;
- if (!struct) struct = Types.structMetadata[typeName.replace(/.*\./, '')];
+ if (!struct) struct = (typeof Types === 'undefined' ? Runtime : Types).structMetadata[typeName.replace(/.*\./, '')];
if (!struct) return null;
- assert(type.fields.length === struct.length, 'Number of named fields must match the type for ' + typeName);
+ assert(type.fields.length === struct.length, 'Number of named fields must match the type for ' + typeName + '. Perhaps due to inheritance, which is not supported yet?');
alignment = type.flatIndexes;
} else {
var type = { fields: struct.map(function(item) { return item[0] }) };
diff --git a/src/settings.js b/src/settings.js
index 226c30b2..ed3437b1 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -63,6 +63,14 @@ SAFE_HEAP_LOG = 0; // Log out all SAFE_HEAP operations
LABEL_DEBUG = 0; // Print out labels and functions as we enter them
EXCEPTION_DEBUG = 1; // Print out exceptions in emscriptened code
+DISABLE_EXCEPTIONS = 0; // Disables generating code to actually catch exceptions. If the code you
+ // are compiling does not actually rely on catching exceptions (but the
+ // compiler generates code for it, maybe because of stdlibc++ stuff),
+ // then this can make it much faster. If an exception actually happens,
+ // it will not be caught and the program will halt (so this will not
+ // introduce silent failures, which is good).
+ // TODO: Make this also remove cxa_begin_catch etc., optimize relooper
+ // for it, etc. (perhaps do all of this as preprocessing on .ll?)
EXECUTION_TIMEOUT = -1; // Throw an exception after X seconds - useful to debug infinite loops
CHECK_OVERFLOWS = 0; // Add code that checks for overflows in integer math operations.
// There is currently not much to do to handle overflows if they occur.