aboutsummaryrefslogtreecommitdiff
path: root/src/jsifier.js
diff options
context:
space:
mode:
authoralon@honor <none@none>2010-10-02 20:27:20 -0700
committeralon@honor <none@none>2010-10-02 20:27:20 -0700
commit72e5d1365603cc107df97f14d2099ee460ec55af (patch)
treea664ad1ae33ea72dbcbe60cfe9d08ca7d5020849 /src/jsifier.js
parent6dcf85c6b014dbc6fc32de186a16b651fcc29b92 (diff)
rewrite of relooper, part I: just emulated and loops, no ifs. all reloop but sauer
Diffstat (limited to 'src/jsifier.js')
-rw-r--r--src/jsifier.js36
1 files changed, 22 insertions, 14 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index 4e47bdf6..a4d7b96e 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -244,6 +244,9 @@ function JSify(data) {
func.JS += ' stackEnter();\n';
if (LABEL_DEBUG) func.JS += " print(INDENT + ' Entering: " + func.ident + "'); INDENT += ' ';\n";
+ if (true) { // TODO: optimize away when not needed
+ func.JS += ' var __label__;\n';
+ }
if (hasVarArgs) {
func.JS += ' __numArgs__ = ' + params.length + ';\n';
}
@@ -254,6 +257,8 @@ function JSify(data) {
// Walk function blocks and generate JS
function walkBlock(block, indent) {
if (!block) return '';
+ if (!block.entry && block.entries.length == 1) block.entry = block.entries[0];
+ dprint('relooping', 'walking block: ' + block.type + ',' + block.entry + ',' + block.entries + ' : ' + block.labels.length);
function getLabelLines(label, indent) {
var ret = '';
if (LABEL_DEBUG) {
@@ -269,25 +274,26 @@ function JSify(data) {
return ret + label.lines.map(function(line) { return indent + line.JS + (line.comment ? ' // ' + line.comment : '') }).join('\n');
}
var ret = '';
- if (block.type == 'emulated' || block.type == 'simple') {
+ if (block.type == 'emulated') {
if (block.labels.length > 1) {
- ret += indent + 'var __label__ = ' + getLabelId(block.entry) + '; /* ' + block.entry + ' */\n';
+ if (block.entry) {
+ ret += indent + '__label__ = ' + getLabelId(block.entry) + '; /* ' + block.entry + ' */\n';
+ } // otherwise, should have been set before!
ret += indent + 'while(1) switch(__label__) {\n';
ret += block.labels.map(function(label) {
return indent + ' case ' + getLabelId(label.ident) + ': // ' + label.ident + '\n'
+ getLabelLines(label, indent + ' ');
}).join('\n');
- ret += '\n' + indent + '}';
+ ret += '\n' + indent + ' default: assert(0, "bad label: " + __label__);\n' + indent + '}';
} else {
ret += getLabelLines(block.labels[0], indent);
}
ret += '\n';
- } else if (block.type == 'loop') {
-// if (mustGetTo(first.outLabels[0], [first.ident, first.outLabels[1]])) { /* left branch must return here, or go to right branch */
+ } else if (block.type == 'reloop') {
ret += indent + block.entry + ': while(1) {\n';
- ret += walkBlock(block.inc, indent + ' ');
- ret += walkBlock(block.rest, indent + ' ');
+ ret += walkBlock(block.inner, indent + ' ');
ret += indent + '}\n';
+ ret += walkBlock(block.outer, indent);
} else if (block.type == 'breakingif') {
ret += walkBlock(block.check, indent);
ret += indent + block.entry + ': do { if (' + block.ifVar + ') {\n';
@@ -417,10 +423,12 @@ function JSify(data) {
return LABEL_IDs[label] = LABEL_ID_COUNTER ++;
}
- function makeBranch(label) {
+ function makeBranch(label, oldLabel) {
if (label[0] == 'B') {
if (label[1] == 'R') {
- return 'break ' + label.substr(5) + ';';
+ assert(oldLabel);
+ return '__label__ = ' + getLabelId(oldLabel) + '; ' + // TODO: optimize away
+ 'break ' + label.substr(5) + ';';
} else if (label[1] == 'C') {
return 'continue ' + label.substr(5) + ';';
} else { // NOPP
@@ -436,8 +444,8 @@ function JSify(data) {
if (!item.ident) {
return makeBranch(item.label);
} else {
- var labelTrue = makeBranch(item.labelTrue);
- var labelFalse = makeBranch(item.labelFalse);
+ var labelTrue = makeBranch(item.labelTrue, item.old_labelTrue);
+ var labelFalse = makeBranch(item.labelFalse, item.old_labelFalse);
if (labelTrue == ';' && labelFalse == ';') return ';';
var head = 'if (' + item.ident + ') { ';
var head2 = 'if (!(' + item.ident + ')) { ';
@@ -462,11 +470,11 @@ function JSify(data) {
first = false;
}
ret += 'if (' + item.ident + ' == ' + switchLabel.value + ') {\n';
- ret += ' ' + makeBranch(switchLabel.label) + '\n';
+ ret += ' ' + makeBranch(switchLabel.label, switchLabel.old_label) + '\n';
ret += '}\n';
});
ret += 'else {\n';
- ret += makeBranch(item.defaultLabel) + '\n';
+ ret += makeBranch(item.defaultLabel, item.old_defaultLabel) + '\n';
ret += '}\n';
if (item.value) {
ret += ' ' + toNiceIdent(item.value);
@@ -490,7 +498,7 @@ function JSify(data) {
+ '__THREW__ = false } catch(e) { '
+ '__THREW__ = true; '
+ (EXCEPTION_DEBUG ? 'print("Exception: " + e + " : " + (new Error().stack)); ' : '')
- + '} })(); if (!__THREW__) { ' + makeBranch(item.toLabel) + ' } else { ' + makeBranch(item.unwindLabel) + ' }';
+ + '} })(); if (!__THREW__) { ' + makeBranch(item.toLabel, item.old_toLabel) + ' } else { ' + makeBranch(item.unwindLabel, item.old_unwindLabel) + ' }';
return ret;
});
makeFuncLineZyme('load', function(item) {