add extCall_* methods in asm dlopen support, parallel to invoke in that they are able to access other modules, but do not catch exceptions

This commit is contained in:
Alon Zakai 2013-09-03 15:57:31 -07:00
Родитель 1b458cf9c5
Коммит 6eaaebf4dd
3 изменённых файлов: 31 добавлений и 5 удалений

Просмотреть файл

@ -483,6 +483,9 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
shared.Settings.copy(settings)
asm_setup += '\n' + shared.JS.make_invoke(sig) + '\n'
basic_funcs.append('invoke_%s' % sig)
if settings.get('DLOPEN_SUPPORT'):
asm_setup += '\n' + shared.JS.make_extcall(sig) + '\n'
basic_funcs.append('extCall_%s' % sig)
# calculate exports
exported_implemented_functions = list(exported_implemented_functions)

Просмотреть файл

@ -1405,8 +1405,10 @@ function JSify(data, functionsOnly, givenFunctions) {
// We cannot compile assembly. See comment in intertyper.js:'Call'
assert(ident != 'asm', 'Inline assembly cannot be compiled to JavaScript!');
var extCall = false;
if (ASM_JS && funcData.setjmpTable) forceByPointer = true; // in asm.js mode, we must do an invoke for each call
if (ASM_JS && DLOPEN_SUPPORT) invoke = true; // go through invoke so we can access other modules TODO: optimize
if (ASM_JS && DLOPEN_SUPPORT && !invoke) extCall = true; // go out, to be able to access other modules TODO: optimize
ident = Variables.resolveAliasToIdent(ident);
var shortident = ident.slice(1);
@ -1467,7 +1469,7 @@ function JSify(data, functionsOnly, givenFunctions) {
args = args.map(function(arg, i) { return indexizeFunctions(arg, argsTypes[i]) });
if (ASM_JS) {
if (shortident in Functions.libraryFunctions || simpleIdent in Functions.libraryFunctions || byPointerForced || invoke || funcData.setjmpTable) {
if (shortident in Functions.libraryFunctions || simpleIdent in Functions.libraryFunctions || byPointerForced || invoke || extCall || funcData.setjmpTable) {
args = args.map(function(arg, i) { return asmCoercion(arg, argsTypes[i]) });
} else {
args = args.map(function(arg, i) { return asmEnsureFloat(arg, argsTypes[i]) });
@ -1558,16 +1560,16 @@ function JSify(data, functionsOnly, givenFunctions) {
if (ASM_JS) {
assert(returnType.search(/\("'\[,/) == -1); // XXX need isFunctionType(type, out)
Functions.neededTables[sig] = 1;
var functionTableCall = !byPointerForced && !funcData.setjmpTable && !invoke;
var functionTableCall = !byPointerForced && !funcData.setjmpTable && !invoke && !extCall;
if (functionTableCall) {
// normal asm function pointer call
callIdent = '(' + callIdent + ')&{{{ FTM_' + sig + ' }}}'; // the function table mask is set in emscripten.py
} else {
// This is a call through an invoke_*, either a forced one, or a setjmp-required one
// This is a call through an invoke_* or extCall, either a forced one, or a setjmp-required one
// note: no need to update argsTypes at this point
if (byPointerForced) Functions.unimplementedFunctions[callIdent] = sig;
args.unshift(byPointerForced ? Functions.getIndex(callIdent, sig) : asmCoercion(callIdent, 'i32'));
callIdent = 'invoke_' + sig;
callIdent = (extCall ? 'extCall' : 'invoke') + '_' + sig;
}
} else if (SAFE_DYNCALLS) {
assert(!ASM_JS, 'cannot emit safe dyncalls in asm');

Просмотреть файл

@ -1442,6 +1442,27 @@ class JS:
def to_nice_ident(ident): # limited version of the JS function toNiceIdent
return ident.replace('%', '$').replace('@', '_')
@staticmethod
def make_extcall(sig, named=True):
args = ','.join(['a' + str(i) for i in range(1, len(sig))])
args = 'index' + (',' if args else '') + args
# C++ exceptions are numbers, and longjmp is a string 'longjmp'
ret = '''function%s(%s) {
%sModule["dynCall_%s"](%s);
}''' % ((' extCall_' + sig) if named else '', args, 'return ' if sig[0] != 'v' else '', sig, args)
if Settings.DLOPEN_SUPPORT and Settings.ASSERTIONS:
# guard against cross-module stack leaks
ret = ret.replace(') {\n', ''') {
try {
var preStack = asm.stackSave();
''').replace(';\n}', ''';
} finally {
assert(asm.stackSave() == preStack);
}
}''')
return ret
@staticmethod
def make_invoke(sig, named=True):
args = ','.join(['a' + str(i) for i in range(1, len(sig))])