handle odd llvm with branches in the middle of labels; all tests pass
This commit is contained in:
Родитель
1f3de5c76e
Коммит
23515d0605
|
@ -39,6 +39,7 @@ function analyzer(data, givenTypes) {
|
||||||
});
|
});
|
||||||
// Functions & labels
|
// Functions & labels
|
||||||
item.functions = [];
|
item.functions = [];
|
||||||
|
var currLabelFinished; // Sometimes LLVM puts a branch in the middle of a label. We need to ignore all lines after that.
|
||||||
for (var i = 0; i < item.items.length; i++) {
|
for (var i = 0; i < item.items.length; i++) {
|
||||||
var subItem = item.items[i];
|
var subItem = item.items[i];
|
||||||
if (subItem.intertype == 'function') {
|
if (subItem.intertype == 'function') {
|
||||||
|
@ -60,10 +61,18 @@ function analyzer(data, givenTypes) {
|
||||||
} else if (subItem.intertype == 'label') {
|
} else if (subItem.intertype == 'label') {
|
||||||
item.functions.slice(-1)[0].labels.push(subItem);
|
item.functions.slice(-1)[0].labels.push(subItem);
|
||||||
subItem.lines = [];
|
subItem.lines = [];
|
||||||
|
currLabelFinished = false;
|
||||||
} else if (item.functions.length > 0 && item.functions.slice(-1)[0].endLineNum === null) {
|
} else if (item.functions.length > 0 && item.functions.slice(-1)[0].endLineNum === null) {
|
||||||
// Internal line
|
// Internal line
|
||||||
item.functions.slice(-1)[0].lines.push(subItem);
|
if (!currLabelFinished) {
|
||||||
item.functions.slice(-1)[0].labels.slice(-1)[0].lines.push(subItem);
|
item.functions.slice(-1)[0].lines.push(subItem);
|
||||||
|
item.functions.slice(-1)[0].labels.slice(-1)[0].lines.push(subItem);
|
||||||
|
if (subItem.intertype === 'branch') {
|
||||||
|
currLabelFinished = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print('// WARNING: content after a branch in a label, line: ' + subItem.lineNum);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
print("ERROR: what is this? " + JSON.stringify(subItem));
|
print("ERROR: what is this? " + JSON.stringify(subItem));
|
||||||
}
|
}
|
||||||
|
|
|
@ -442,7 +442,7 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions, givenGlobalVaria
|
||||||
if (block.type == 'emulated') {
|
if (block.type == 'emulated') {
|
||||||
if (block.labels.length > 1) {
|
if (block.labels.length > 1) {
|
||||||
if (block.entries.length == 1) {
|
if (block.entries.length == 1) {
|
||||||
ret += indent + '__label__ = ' + getLabelId(block.entries[0]) + '; /* ' + block.entries[0] + ' */\n';
|
ret += indent + '__label__ = ' + getLabelId(block.entries[0]) + '; ' + (SHOW_LABELS ? '/* ' + block.entries[0] + ' */' : '') + '\n';
|
||||||
} // otherwise, should have been set before!
|
} // otherwise, should have been set before!
|
||||||
ret += indent + 'while(1) switch(__label__) {\n';
|
ret += indent + 'while(1) switch(__label__) {\n';
|
||||||
ret += block.labels.map(function(label) {
|
ret += block.labels.map(function(label) {
|
||||||
|
@ -451,11 +451,11 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions, givenGlobalVaria
|
||||||
}).join('\n');
|
}).join('\n');
|
||||||
ret += '\n' + indent + ' default: assert(0, "bad label: " + __label__);\n' + indent + '}';
|
ret += '\n' + indent + ' default: assert(0, "bad label: " + __label__);\n' + indent + '}';
|
||||||
} else {
|
} else {
|
||||||
ret += getLabelLines(block.labels[0], indent);
|
ret += (SHOW_LABELS ? indent + '/* ' + block.entries[0] + ' */' : '') + '\n' + getLabelLines(block.labels[0], indent);
|
||||||
}
|
}
|
||||||
ret += '\n';
|
ret += '\n';
|
||||||
} else if (block.type == 'reloop') {
|
} else if (block.type == 'reloop') {
|
||||||
ret += indent + block.id + ': while(1) { // ' + block.entries + '\n';
|
ret += indent + block.id + ': while(1) { ' + (SHOW_LABELS ? ' /* ' + block.entries + + ' */' : '') + '\n';
|
||||||
ret += walkBlock(block.inner, indent + ' ');
|
ret += walkBlock(block.inner, indent + ' ');
|
||||||
ret += indent + '}\n';
|
ret += indent + '}\n';
|
||||||
} else if (block.type == 'multiple') {
|
} else if (block.type == 'multiple') {
|
||||||
|
@ -632,7 +632,7 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions, givenGlobalVaria
|
||||||
var parts = label.split('|');
|
var parts = label.split('|');
|
||||||
var trueLabel = parts[1];
|
var trueLabel = parts[1];
|
||||||
var oldLabel = parts[2];
|
var oldLabel = parts[2];
|
||||||
var labelSetting = '__label__ = ' + getLabelId(oldLabel) + '; /* ' + cleanLabel(oldLabel) + ' */ '; // TODO: optimize away
|
var labelSetting = '__label__ = ' + getLabelId(oldLabel) + ';' + (SHOW_LABELS ? ' /* to: ' + cleanLabel(oldLabel) + ' */' : ''); // TODO: optimize away
|
||||||
if (label[1] == 'R') {
|
if (label[1] == 'R') {
|
||||||
return pre + labelSetting + 'break ' + trueLabel + ';';
|
return pre + labelSetting + 'break ' + trueLabel + ';';
|
||||||
} else if (label[1] == 'C') { // CONT
|
} else if (label[1] == 'C') { // CONT
|
||||||
|
@ -645,7 +645,7 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions, givenGlobalVaria
|
||||||
throw 'Invalid B-op in branch: ' + trueLabel + ',' + oldLabel;
|
throw 'Invalid B-op in branch: ' + trueLabel + ',' + oldLabel;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return pre + '__label__ = ' + getLabelId(label) + '; /* ' + cleanLabel(label) + ' */ break;';
|
return pre + '__label__ = ' + getLabelId(label) + ';' + (SHOW_LABELS ? ' /* to: ' + cleanLabel(label) + ' */' : '') + ' break;';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,8 @@ CORRECT_OVERFLOWS = 1; // Experimental code that tries to prevent unexpected JS
|
||||||
// not rely on overflows in your C/C++ code, as even if this option works,
|
// not rely on overflows in your C/C++ code, as even if this option works,
|
||||||
// it slows things down.
|
// it slows things down.
|
||||||
|
|
||||||
|
SHOW_LABELS = 0; // Show labels in the generated code
|
||||||
|
|
||||||
// Compiler debugging options
|
// Compiler debugging options
|
||||||
DEBUG_TAGS_SHOWING = [];
|
DEBUG_TAGS_SHOWING = [];
|
||||||
// Some useful items:
|
// Some useful items:
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
@.str = private constant [15 x i8] c"hello, world!\0A\00", align 1 ; [#uses=1]
|
||||||
|
|
||||||
|
define linkonce_odr i32* @main() align 2 {
|
||||||
|
%199 = trunc i8 1 to i1 ; [#uses=1]
|
||||||
|
br i1 %199, label %555, label %569
|
||||||
|
|
||||||
|
; <label>:555 ; preds = %353
|
||||||
|
br label %569
|
||||||
|
; No predecessors!
|
||||||
|
br label %569
|
||||||
|
|
||||||
|
; <label>:569 ; preds = %555
|
||||||
|
%333 = call i32 @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0]
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i32 @printf(i8*)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче