aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-04-11 21:18:37 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-04-11 21:18:37 -0700
commit9e7a712c6b6186792f186ed6bd6d6af31d36a434 (patch)
treeed0b51d1f165dc80278aedf9f3f768fe303aff15
parentfd301b105745a855e4cb231e217e8acf40df1858 (diff)
infrastructure for supporting exceptions in asm.js, by going through invoke_* calls
-rwxr-xr-xemscripten.py3
-rw-r--r--src/compiler.js1
-rw-r--r--src/jsifier.js25
-rw-r--r--src/library.js1
-rw-r--r--src/settings.js2
5 files changed, 22 insertions, 10 deletions
diff --git a/emscripten.py b/emscripten.py
index 502e951c..996e5cc3 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -414,12 +414,13 @@ var i64Math_modulo = function(a, b, c, d, e) { i64Math.modulo(a, b, c, d, e) };
}
''' % (sig, ',' if len(sig) > 1 else '', args, arg_coercions, ret))
args = ','.join(['a' + str(i) for i in range(1, len(sig))])
+ args = 'index' + (',' if args else '') + args
asm_setup += '''
function invoke_%s(%s) {
try {
%sModule.dynCall_%s(%s);
} catch(e) {
- Module.setThrew(1);
+ asm.setThrew(1);
}
}
''' % (sig, args, 'return ' if sig[0] != 'v' else '', sig, args)
diff --git a/src/compiler.js b/src/compiler.js
index 7cf43f09..9c19aeb0 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -178,7 +178,6 @@ assert(!(USE_TYPED_ARRAYS === 2 && QUANTUM_SIZE !== 4), 'For USE_TYPED_ARRAYS ==
if (ASM_JS) {
assert(!ALLOW_MEMORY_GROWTH, 'Cannot grow asm.js heap');
assert((TOTAL_MEMORY&(TOTAL_MEMORY-1)) == 0, 'asm.js heap must be power of 2');
- assert(DISABLE_EXCEPTION_CATCHING == 1, 'asm.js does not support C++ exceptions yet, you must compile with -s DISABLE_EXCEPTION_CATCHING=1');
}
assert(!(!NAMED_GLOBALS && BUILD_AS_SHARED_LIB)); // shared libraries must have named globals
diff --git a/src/jsifier.js b/src/jsifier.js
index 0786f622..af07539f 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1156,12 +1156,13 @@ function JSify(data, functionsOnly, givenFunctions) {
makeFuncLineActor('invoke', function(item) {
// Wrapping in a function lets us easily return values if we are
// in an assignment
+ var disabled = DISABLE_EXCEPTION_CATCHING == 2 && !(item.funcData.ident in EXCEPTION_CATCHING_WHITELIST);
var phiSets = calcPhiSets(item);
- var call_ = makeFunctionCall(item.ident, item.params, item.funcData, item.type);
-
+ var call_ = makeFunctionCall(item.ident, item.params, item.funcData, item.type, ASM_JS && !disabled);
+
var ret;
- if (DISABLE_EXCEPTION_CATCHING == 2 && !(item.funcData.ident in EXCEPTION_CATCHING_WHITELIST)) {
+ if (disabled || ASM_JS) { // TODO: EXCEPTION_DEBUG for asm.js
ret = call_ + ';';
} else {
ret = '(function() { try { __THREW__ = 0; return '
@@ -1173,7 +1174,6 @@ function JSify(data, functionsOnly, givenFunctions) {
+ 'return null } })();';
}
-
if (item.assignTo) {
ret = 'var ' + item.assignTo + ' = ' + ret;
if (USE_TYPED_ARRAYS == 2 && isIllegalType(item.type)) {
@@ -1291,7 +1291,7 @@ function JSify(data, functionsOnly, givenFunctions) {
return ret;
});
- function makeFunctionCall(ident, params, funcData, type) {
+ function makeFunctionCall(ident, params, funcData, type, forceByPointer) {
// We cannot compile assembly. See comment in intertyper.js:'Call'
assert(ident != 'asm', 'Inline assembly cannot be compiled to JavaScript!');
@@ -1319,6 +1319,11 @@ function JSify(data, functionsOnly, givenFunctions) {
var hasVarArgs = isVarArgsFunctionType(type);
var normalArgs = (hasVarArgs && !useJSArgs) ? countNormalArgs(type) : -1;
var byPointer = getVarData(funcData, ident);
+ var byPointerForced = false;
+
+ if (forceByPointer && !byPointer) {
+ byPointer = byPointerForced = true;
+ }
params.forEach(function(param, i) {
var val = finalizeParam(param);
@@ -1421,12 +1426,18 @@ function JSify(data, functionsOnly, givenFunctions) {
var sig = Functions.getSignature(returnType, argsTypes, hasVarArgs);
if (ASM_JS) {
assert(returnType.search(/\("'\[,/) == -1); // XXX need isFunctionType(type, out)
- callIdent = '(' + callIdent + ')&{{{ FTM_' + sig + ' }}}'; // the function table mask is set in emscripten.py
+ if (!forceByPointer) {
+ callIdent = '(' + callIdent + ')&{{{ FTM_' + sig + ' }}}'; // the function table mask is set in emscripten.py
+ } else {
+ // add initial argument for invoke. note: no need to update argsTypes at this point
+ args.unshift(byPointerForced ? Functions.getIndex(callIdent) : callIdent);
+ callIdent = 'invoke_' + sig;
+ }
} else if (SAFE_DYNCALLS) {
assert(!ASM_JS, 'cannot emit safe dyncalls in asm');
callIdent = '(tempInt=' + callIdent + ',tempInt < 0 || tempInt >= FUNCTION_TABLE.length-1 || !FUNCTION_TABLE[tempInt] ? abort("dyncall error: ' + sig + ' " + FUNCTION_TABLE_NAMES[tempInt]) : tempInt)';
}
- callIdent = Functions.getTable(sig) + '[' + callIdent + ']';
+ if (!byPointerForced) callIdent = Functions.getTable(sig) + '[' + callIdent + ']';
}
var ret = callIdent + '(' + args.join(', ') + ')';
diff --git a/src/library.js b/src/library.js
index 01c0a3f3..80c107a5 100644
--- a/src/library.js
+++ b/src/library.js
@@ -5016,6 +5016,7 @@ LibraryManager.library = {
__cxa_free_exception: function(ptr) {
return _free(ptr);
},
+ __cxa_throw__sig: 'viii',
__cxa_throw__deps: ['llvm_eh_exception', '_ZSt18uncaught_exceptionv', '__cxa_find_matching_catch'],
__cxa_throw: function(ptr, type, destructor) {
if (!___cxa_throw.initialized) {
diff --git a/src/settings.js b/src/settings.js
index 08dad7f7..8f31c2d8 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -150,7 +150,7 @@ var LABEL_FUNCTION_FILTERS = []; // Filters for function label debug.
// labels of functions that is equaled to
// one of the filters are printed out
// When the array is empty, the filter is disabled.
-var EXCEPTION_DEBUG = 0; // Print out exceptions in emscriptened code
+var EXCEPTION_DEBUG = 0; // Print out exceptions in emscriptened code. Does not work in asm.js mode
var LIBRARY_DEBUG = 0; // Print out when we enter a library call (library*.js). You can also unset
// Runtime.debug at runtime for logging to cease, and can set it when you