make sure to set label if label is used in the emterpreter, as we will run aggressiveVariableElimination after it is no longer identifiable

This commit is contained in:
Alon Zakai 2015-03-18 14:46:35 -07:00
Родитель b89f32dfea
Коммит 919d74e9bd
4 изменённых файлов: 4840 добавлений и 3 удалений

6
emcc
Просмотреть файл

@ -1495,12 +1495,16 @@ try:
js_optimizer_queue += [get_eliminate()]
if shared.Settings.AGGRESSIVE_VARIABLE_ELIMINATION:
# note that this happens before registerize/minification, which can obfuscate the name of 'label', which is tricky
js_optimizer_queue += ['aggressiveVariableElimination']
js_optimizer_queue += ['simplifyExpressions']
if shared.Settings.EMTERPRETIFY: # emterpreter code will not run through a JS optimizing JIT, do more work ourselves
if shared.Settings.EMTERPRETIFY:
# emterpreter code will not run through a JS optimizing JIT, do more work ourselves
js_optimizer_queue += ['localCSE']
# add explicit label setting, as we will run aggressiveVariableElimination late, *after* 'label' is no longer notable by name
js_optimizer_queue += ['safeLabelSetting']
if shared.Settings.RELOOP and not shared.Settings.ASM_JS:
js_optimizer_queue += ['optimizeShiftsAggressive', get_eliminate()] # aggressive shifts optimization requires loops, it breaks on switches

4807
tests/fuzz/24.cpp Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

1
tests/fuzz/24.cpp.txt Normal file
Просмотреть файл

@ -0,0 +1 @@
checksum = 1A282BA8

Просмотреть файл

@ -1075,6 +1075,30 @@ function localCSE(ast) {
});
}
function safeLabelSetting(ast) {
// Add an assign to label, if it exists, so that even after we minify/registerize variable names, we can tell if any vars use the asm init value of 0 - none will, so it's easy to tell
assert(asm);
traverseGeneratedFunctions(ast, function(func) {
var asmData = normalizeAsm(func);
if ('label' in asmData.vars) {
var stats = getStatements(func);
var seenVar = false;
for (var i = 0; i < stats.length; i++) {
var curr = stats[i];
if (curr[0] === 'stat') curr = curr[1];
if (curr[0] === 'var') {
seenVar = true;
} else if (seenVar && curr[0] !== 'var') {
// first location after the vars
stats.splice(i+1, 0, ['stat', ['assign', true, ['name', 'label'], ['num', 0]]]);
break;
}
}
}
denormalizeAsm(func, asmData);
});
}
function simplifyIfs(ast) {
traverseGeneratedFunctions(ast, function(func) {
var simplifiedAnElse = false;
@ -6326,7 +6350,7 @@ function emterpretify(ast) {
}
case 'var':
case 'toplevel': {
assert(dropIt);
assert(dropIt || isEmptyNode(node));
return [-1, []]; // empty node
}
case 'stat': return getReg(node[1], dropIt);
@ -7229,7 +7253,7 @@ function emterpretify(ast) {
stats.forEach(function(stat) {
var before = freeLocals.length;
var raw = getReg(stat, true);
//printErr('raw: ' + JSON.stringify(raw));
//printErr('raw: ' + JSON.stringify(stat));
releaseIfFree(raw[0]);
if (freeLocals.length !== before) assert(0, [before, freeLocals.length] + ' due to ' + astToSrc(stat)); // the statement is done - nothing should still be held on to
var curr = raw[1];
@ -7895,6 +7919,7 @@ var passes = {
optimizeShiftsConservative: optimizeShiftsConservative,
optimizeShiftsAggressive: optimizeShiftsAggressive,
localCSE: localCSE,
safeLabelSetting: safeLabelSetting,
simplifyIfs: simplifyIfs,
hoistMultiples: hoistMultiples,
loopOptimizer: loopOptimizer,