aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-12-09 11:25:29 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-12-09 11:25:29 -0800
commit22dd25322a59b779389a0ff702e021dc2b328dbf (patch)
treeb475d5f7fcf75e7078b86c69013e362f20536335 /src
parentcc3d094151bf9b2652be290645ddd7a094f3ea3e (diff)
parent0390d4961c52f09b9528ab89ce5190fc9a470f49 (diff)
merge incoming
Diffstat (limited to 'src')
-rw-r--r--src/intertyper.js1
-rw-r--r--src/jsifier.js8
-rw-r--r--src/library.js4
-rw-r--r--src/preamble.js2
4 files changed, 10 insertions, 5 deletions
diff --git a/src/intertyper.js b/src/intertyper.js
index f63e0982..2de6c6b9 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -926,6 +926,7 @@ function intertyper(data, sidePass, baseLineNums) {
processItem: function(item) {
return [{
intertype: 'resume',
+ ident: toNiceIdent(item.tokens[2].text),
lineNum: item.lineNum
}];
}
diff --git a/src/jsifier.js b/src/jsifier.js
index a6a3fb28..0e8b825a 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -664,7 +664,7 @@ function JSify(data, functionsOnly, givenFunctions) {
} // otherwise, should have been set before!
if (func.setjmpTable) {
var setjmpTable = {};
- ret += indent + 'var setjmped = false;'; // set to true if we setjmp in this invocation
+ ret += indent + 'var mySetjmpIds = {};\n';
ret += indent + 'var setjmpTable = {';
func.setjmpTable.forEach(function(triple) { // original label, label we created for right after the setjmp, variable setjmp result goes into
ret += '"' + getLabelId(triple[0]) + '": ' + 'function(value) { label = ' + getLabelId(triple[1]) + '; ' + triple[2] + ' = value },';
@@ -683,7 +683,7 @@ function JSify(data, functionsOnly, givenFunctions) {
}).join('\n');
ret += '\n' + indent + ' default: assert(0, "bad label: " + label);\n' + indent + '}';
if (func.setjmpTable) {
- ret += ' } catch(e) { if (!setjmped) throw(e); if (!e.longjmp) throw(e); setjmpTable[e.label](e.value) }';
+ ret += ' } catch(e) { if (!e.longjmp || !(e.id in mySetjmpIds)) throw(e); setjmpTable[setjmpLabels[e.id]](e.value) }';
}
} else {
ret += (SHOW_LABELS ? indent + '/* ' + block.entries[0] + ' */' : '') + '\n' + getLabelLines(block.labels[0], indent);
@@ -1081,8 +1081,10 @@ function JSify(data, functionsOnly, givenFunctions) {
return ret + ';';
});
makeFuncLineActor('resume', function(item) {
+ // If there is no current exception, set this one as it (during a resume, the current exception can be wiped out)
return (EXCEPTION_DEBUG ? 'Module.print("Resuming exception");' : '') +
- 'throw ' + makeGetValue('_llvm_eh_exception.buf', '0', 'void*') + ';';
+ 'if (' + makeGetValue('_llvm_eh_exception.buf', 0, 'void*') + ' == 0) { ' + makeSetValue('_llvm_eh_exception.buf', 0, item.ident + '.f0', 'void*') + ' } ' +
+ 'throw ' + item.ident + '.f0;';
});
makeFuncLineActor('invoke', function(item) {
// Wrapping in a function lets us easily return values if we are
diff --git a/src/library.js b/src/library.js
index f23e87f7..5834797f 100644
--- a/src/library.js
+++ b/src/library.js
@@ -5922,11 +5922,11 @@ LibraryManager.library = {
setjmp__inline: function(env) {
// Save the label
- return '(setjmped = true, ' + makeSetValue(env, '0', 'label', 'i32') + ', 0)';
+ return '(tempInt = setjmpId++, mySetjmpIds[tempInt] = 1, setjmpLabels[tempInt] = label,' + makeSetValue(env, '0', 'tempInt', 'i32') + ', 0)';
},
longjmp: function(env, value) {
- throw { longjmp: true, label: {{{ makeGetValue('env', '0', 'i32') }}}, value: value || 1 };
+ throw { longjmp: true, id: {{{ makeGetValue('env', '0', 'i32') }}}, value: value || 1 };
},
// ==========================================================================
diff --git a/src/preamble.js b/src/preamble.js
index ae264a90..b28dfc0d 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -276,6 +276,8 @@ Module['printProfiling'] = printProfiling;
//========================================
var __THREW__ = 0; // Used in checking for thrown exceptions.
+var setjmpId = 1; // Used in setjmp/longjmp
+var setjmpLabels = {};
var ABORT = false;