diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analyzer.js | 14 | ||||
-rw-r--r-- | src/intertyper.js | 8 | ||||
-rw-r--r-- | src/jsifier.js | 10 | ||||
-rw-r--r-- | src/parseTools.js | 12 | ||||
-rw-r--r-- | src/preamble.js | 6 | ||||
-rw-r--r-- | src/runtime.js | 6 | ||||
-rw-r--r-- | src/settings.js | 8 |
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. |