aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralon@honor <none@none>2010-10-04 21:15:59 -0700
committeralon@honor <none@none>2010-10-04 21:15:59 -0700
commitccb8f47e51e20d0735f5478dd403309e43985a8a (patch)
tree51a92ec2c55eba7a47d54976617db8fec18261c3
parentd4d0a06a49dba346ad20bce3392fb677822b0eb9 (diff)
GUARD_LABELS option + further cleanup
-rw-r--r--src/analyzer.js82
-rw-r--r--src/jsifier.js4
-rw-r--r--src/settings.js2
3 files changed, 45 insertions, 43 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index f039023e..9032da3e 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -298,20 +298,16 @@ function analyzer(data) {
// Tools
- function replaceLabels(line, labelIds, toLabelId) {
- var ret = [];
- function process(item) {
+ var BRANCH_INVOKE = searchable('branch', 'invoke');
+ function operateOnLabels(line, func) {
+ function process(item, id) {
['label', 'labelTrue', 'labelFalse', 'toLabel', 'unwindLabel', 'defaultLabel'].forEach(function(id) {
- if (item[id] && item[id] in labelIds) {
- ret.push(item[id]);
- assert(!item['old_' + id]);
- item['old_' + id] = item[id]; // Save it; we need this later for labels before breaks, when we have multiple entries later
- dprint('relooping', 'zz ' + id + ' replace ' + item[id] + ' with ' + toLabelId + '; old: ' + item['old_' + id]);
- item[id] = toLabelId;
+ if (item[id]) {
+ func(item, id);
}
});
}
- if (['branch', 'invoke'].indexOf(line.intertype) != -1) {
+ if (line.intertype in BRANCH_INVOKE) {
process(line);
} else if (line.intertype == 'assign' && line.value.intertype == 'invoke') {
process(line.value);
@@ -319,6 +315,19 @@ function analyzer(data) {
process(line);
line.switchLabels.forEach(process);
}
+ }
+
+ function replaceLabels(line, labelIds, toLabelId) {
+ var ret = [];
+ operateOnLabels(line, function process(item, id) {
+ if (item[id] in labelIds) {
+ ret.push(item[id]);
+ assert(!item['old_' + id]);
+ item['old_' + id] = item[id]; // Save it; we need this later for labels before breaks, when we have multiple entries later
+ dprint('relooping', 'zz ' + id + ' replace ' + item[id] + ' with ' + toLabelId + '; old: ' + item['old_' + id]);
+ item[id] = toLabelId;
+ }
+ });
return ret;
}
@@ -342,26 +351,14 @@ function analyzer(data) {
// Find direct branchings
labels.forEach(function(label) {
label.lines.forEach(function(line) {
- function process(item) {
- ['label', 'labelTrue', 'labelFalse', 'toLabel', 'unwindLabel', 'defaultLabel'].forEach(function(id) {
- if (item[id]) {
- if (item[id][0] == 'B') { // BREAK, BCONT, BNOPP
- label.hasBreak = true;
- } else {
- label.outLabels.push(item[id]);
- labelsDict[item[id]].inLabels.push(label.ident);
- }
- }
- });
- }
- if (['branch', 'invoke'].indexOf(line.intertype) != -1) {
- process(line);
- } else if (line.intertype == 'assign' && line.value.intertype == 'invoke') {
- process(line.value);
- } else if (line.intertype == 'switch') {
- process(line);
- line.switchLabels.forEach(process);
- }
+ operateOnLabels(line, function process(item, id) {
+ if (item[id][0] == 'B') { // BREAK, BCONT, BNOPP, BJSET
+ label.hasBreak = true;
+ } else {
+ label.outLabels.push(item[id]);
+ labelsDict[item[id]].inLabels.push(label.ident);
+ }
+ });
label.hasReturn |= line.intertype == 'return';
});
@@ -393,22 +390,22 @@ function analyzer(data) {
});
}
- if (dcheck('relooping')) {
- labels.forEach(function(label) {
+ labels.forEach(function(label) {
+ if (dcheck('relooping')) {
dprint('// label: ' + label.ident + ' :out : ' + JSON.stringify(label.outLabels));
dprint('// ' + label.ident + ' :in : ' + JSON.stringify(label.inLabels));
dprint('// ' + label.ident + ' :ALL out : ' + JSON.stringify(label.allOutLabels));
dprint('// ' + label.ident + ' :ALL in : ' + JSON.stringify(label.allInLabels));
+ }
- // Convert to searchables, for speed (we mainly do lookups here) and code clarity (x in Xlabels)
- // Also removes duplicates (which we can get in llvm switches)
- // FIXME TODO XXX do we need all these?
- label.outLabels = searchable(label.outLabels);
- label.inLabels = searchable(label.inLabels);
- label.allOutLabels = searchable(label.allOutLabels);
- label.allInLabels = searchable(label.allInLabels);
- });
- }
+ // Convert to searchables, for speed (we mainly do lookups here) and code clarity (x in Xlabels)
+ // Also removes duplicates (which we can get in llvm switches)
+ // FIXME TODO XXX do we need all these?
+ label.outLabels = searchable(label.outLabels);
+ label.inLabels = searchable(label.inLabels);
+ label.allOutLabels = searchable(label.allOutLabels);
+ label.allInLabels = searchable(label.allInLabels);
+ });
}
// There are X main kinds of blocks:
@@ -605,7 +602,8 @@ function analyzer(data) {
if (handlingNow.length == 0) {
// spaghetti - cannot even find a single label to do before the rest. What a mess.
- dprint('relooping', ' Creating complex emulated');
+ // TODO: try a loop, if possible?
+ dprint('relooping', ' WARNING: Creating complex emulated');
return emulated;
}
diff --git a/src/jsifier.js b/src/jsifier.js
index 4aee5a7c..b4b0952f 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -323,7 +323,9 @@ function JSify(data) {
ret += indent + ' }\n';
first = false;
});
- ret += indent + ' else { throw "Bad multiple branching: " + __label__ + " : " + (new Error().stack); }\n';
+ if (GUARD_LABELS) {
+ ret += indent + ' else { throw "Bad multiple branching: " + __label__ + " : " + (new Error().stack); }\n';
+ }
ret += indent + '} while(0);\n';
} else {
throw "Walked into an invalid block type: " + block.type;
diff --git a/src/settings.js b/src/settings.js
index 176d6667..27dbf7f4 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -16,6 +16,8 @@ QUANTUM_SIZE = 1; // This is the size of an individual field in a structure. 1 w
GUARD_SIGNS = 1; // Whether we make sure to convert unsigned values to signed values.
// Decreases performance with additional runtime checks. Might not be
// needed in some kinds of code.
+GUARD_LABELS = 0; // Whether we should throw if we encounter a bad __label__, i.e.,
+ // if code flow runs into a fault
// Code embetterments
OPTIMIZE = 0; // Optimize llvm operations into js commands