diff options
-rw-r--r-- | src/analyzer.js | 29 | ||||
-rw-r--r-- | src/jsifier.js | 16 | ||||
-rw-r--r-- | src/parseTools.js | 8 | ||||
-rw-r--r-- | src/runtime.js | 8 |
4 files changed, 48 insertions, 13 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index ce4a99af..2418170c 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -300,7 +300,34 @@ function analyzer(data) { }); }); }); - this.forwardItem(item, 'Relooper'); + this.forwardItem(item, 'StackAnalyzer'); + }, + }); + + // Stack analyzer - calculate the base stack usage + substrate.addZyme('StackAnalyzer', { + processItem: function(data) { + data.functions.forEach(function(func) { + var total = 0; + var lines = func.labels[0].lines; + for (var i = 0; i < lines.length; i++) { + var item = lines[i].value; + if (!item || item.intertype != 'alloca') break; + // FIXME: This ignores nativized variables, but probably negligible + item.allocatedSize = calcAllocatedSize(item.allocatedType, data.types); + total += item.allocatedSize; + } + func.initialStack = total; + var index = 0; + for (var i = 0; i < lines.length; i++) { + var item = lines[i].value; + if (!item || item.intertype != 'alloca') break; + index += item.allocatedSize; + item.allocatedIndex = index; + delete item.allocatedSize; + } + }); + this.forwardItem(data, 'Relooper'); }, }); diff --git a/src/jsifier.js b/src/jsifier.js index 547bde72..955fa900 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -276,7 +276,9 @@ function JSify(data) { }).filter(function(param) { return param != null });; func.JS = '\nfunction ' + func.ident + '(' + params.join(', ') + ') {\n'; - func.JS += ' ' + RuntimeGenerator.stackEnter() + '\n'; + + func.JS += ' ' + RuntimeGenerator.stackEnter(func.initialStack) + ';\n'; + if (LABEL_DEBUG) func.JS += " print(INDENT + ' Entering: " + func.ident + "'); INDENT += ' ';\n"; if (true) { // TODO: optimize away when not needed @@ -591,15 +593,10 @@ function JSify(data) { return item.ident + '.f' + item.indexes[0][0].text; }); makeFuncLineZyme('alloca', function(item) { - dprint('alloca', dump(item)); - if (pointingLevels(item.allocatedType) == 0 && isStructType(item.allocatedType)) { - return RuntimeGenerator.stackAlloc(makeEmptyStruct(item.allocatedType).length); - } else { - return RuntimeGenerator.stackAlloc(1); - } + assert(typeof item.allocatedIndex === 'number'); // or, return RuntimeGenerator.stackAlloc(calcAllocatedSize(item.allocatedType, TYPES)); + return getFastValue('STACKTOP', '-', item.allocatedIndex.toString()); }); makeFuncLineZyme('phi', function(item) { - dprint('phi', dump(item)); return '__lastLabel__ == ' + getLabelId(item.label1) + ' ? ' + toNiceIdent(item.value1) + ' : ' + toNiceIdent(item.value2); }); @@ -612,7 +609,6 @@ function JSify(data) { } makeFuncLineZyme('mathop', function(item) { with(item) { - dprint('mathop', 'mathop: ' + dump(item)); for (var i = 1; i <= 4; i++) { if (item['param'+i]) { item['ident'+i] = finalizeLLVMParameter(item['param'+i]); @@ -705,7 +701,7 @@ function JSify(data) { } else if (b == 1) { return a; } - } else if (op == '+') { + } else if (op in set('+', '-')) { if (!a) a = 0; if (!b) b = 0; if (a == 0) { diff --git a/src/parseTools.js b/src/parseTools.js index 4d1ed438..ca96ba65 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -446,3 +446,11 @@ function cleanLabel(label) { } } +function calcAllocatedSize(type, TYPES) { + if (pointingLevels(type) == 0 && isStructType(type)) { + return TYPES[type].flatSize; // makeEmptyStruct(item.allocatedType).length; + } else { + return 1; + } +} + diff --git a/src/runtime.js b/src/runtime.js index 346020b0..0ae70fa3 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -25,8 +25,12 @@ RuntimeGenerator = { return ret; }, - stackEnter: function() { - return 'STACK_STACK.push(STACKTOP);'; + stackEnter: function(initial) { + var ret = 'STACK_STACK.push(STACKTOP); STACKTOP += ' + initial; + if (GUARD_MEMORY) { + ret += '; assert(STACKTOP < STACK_MAX)'; + } + return ret; }, stackExit: function() { |