Fix quadratic CL asm parsing

dev/git-series/gccdum
Matt Godbolt 7 years ago
parent 7f3267a867
commit 850ee6f9ef

@ -123,10 +123,22 @@ ClParser.prototype._add = function (obj) {
obj.opcodes = this.opcoder.opcodes;
obj.address = this.opcoder.offset;
}
if (obj.keep) {
this.markUsed(obj.lineLabels);
}
this.result.push(obj);
debug(obj);
};
ClParser.prototype.markUsed = function (lineLabels) {
_.each(lineLabels, function (val, label) {
if (!this.labels[label]) {
debug("Marking " + label + " as used");
}
this.labels[label] = true;
}, this);
};
ClParser.prototype.addLine = function (line) {
if (!!line.match(ignoreAll)) return;
line = this.opcoder.onLine(line);
@ -156,12 +168,12 @@ ClParser.prototype.addLine = function (line) {
var isIndented = match[1] !== "";
var command = match[2];
var comment = match[3] || "";
var lineLabels = {};
_.each(command.match(labelFind), function (label) {
lineLabels[label] = true;
}, this);
if (isIndented && this.opcoder.hasOpcodes()) {
this._add({keep: true, text: " " + command + comment, source: this.source});
match = command.match(labelFind);
_.each(match, function (label) {
this.labels[label] = true;
}, this);
this._add({keep: true, lineLabels: lineLabels, text: " " + command + comment, source: this.source});
} else {
var keep = !this.filters.directives;
if (command.match(isProc))
@ -183,28 +195,32 @@ ClParser.prototype.addLine = function (line) {
debug(match, this.currentLabel);
tempDef = true;
}
this._add({keep: keep, text: command + comment, source: null});
this._add({keep: keep, lineLabels: lineLabels, text: command + comment, source: null});
if (tempDef) this.currentLabel = null;
}
};
ClParser.prototype.findUsed = function () {
// TODO: quadratic!
ClParser.prototype.findUsedInternal = function () {
var changed = false;
var findUsedInternal = function (key, label) {
_.each(this.result, function (obj) {
if (!obj.keep && obj.label == label) {
debug("Keeping", obj, "due to", label);
obj.keep = true;
changed = true;
}
}, this);
};
_.each(this.result, function (obj) {
if (obj.keep || !this.labels[obj.label]) {
return;
}
debug("Keeping", obj);
obj.keep = true;
this.markUsed(obj.lineLabels);
changed = true;
}, this);
debug("changed", changed);
return changed;
};
ClParser.prototype.findUsed = function () {
// TODO write tests that cover dependent labels being used.
var MaxIterations = 100;
for (var i = 0; i < MaxIterations; ++i) {
changed = false;
_.each(this.labels, findUsedInternal, this);
if (!changed) return;
if (!this.findUsedInternal())
return;
}
};

Loading…
Cancel
Save