diff options
-rw-r--r-- | emlink.py | 20 | ||||
-rwxr-xr-x | emscripten.py | 16 | ||||
-rw-r--r-- | tools/shared.py | 14 |
3 files changed, 36 insertions, 14 deletions
@@ -17,6 +17,13 @@ Limitations: * We duplicate code in some cases, like overlapping names in different modules, and function aliases * We do not handle sharing of global constants across modules, only code (you can make a function to access a constant, if you need that) + * We do not link in compiled libraries (libc, libc++, etc.) in side modules. If the main module + does not automatically link in the ones that side modules will need, you should compile the + main module with + + EMCC_FORCE_STDLIBS=1 emcc .. + + which will link in all the C libraries. Overall, this linking approach should be fast to perform, but generate less-optimal results than to link all the bitcode together and build to JS as a single project. Final builds should be @@ -96,6 +103,7 @@ class AsmModule(): # post self.post_js = self.js[self.end_asm:] + self.sendings = set([sending.strip() for sending in self.post_js[self.post_js.find('}, { ')+5:self.post_js.find(' }, buffer);')].split(',')]) self.module_defs = set(re.findall('var [\w\d_$]+ = Module\["[\w\d_$]+"\] = asm\["[\w\d_$]+"\];\n', self.post_js)) def relocate_into(self, main): @@ -123,6 +131,18 @@ class AsmModule(): replacements[func] = rep #print >> sys.stderr, 'replacements:', replacements + # sendings: add invokes for new tables + new_sendings = [] + for table in self.tables: + if table not in main.tables: + sig = table[table.rfind('_')+1:] + new_sendings.append('"invoke_%s": %s' % (sig, shared.JS.make_invoke(sig, named=False))) + if new_sendings: + sendings_js = ', '.join(main.sendings.union(new_sendings)) + sendings_start = main.post_js.find('}, { ')+5 + sendings_end = main.post_js.find(' }, buffer);') + main.post_js = main.post_js[:sendings_start] + sendings_js + main.post_js[sendings_end:] + # tables f_bases = {} f_sizes = {} diff --git a/emscripten.py b/emscripten.py index 56f59273..26e9f44f 100755 --- a/emscripten.py +++ b/emscripten.py @@ -11,6 +11,7 @@ headers, for the libc implementation in JS). import os, sys, json, optparse, subprocess, re, time, multiprocessing, functools +from tools import shared from tools import jsrun, cache as cache_module, tempfiles from tools.response_file import read_response_file @@ -25,7 +26,6 @@ def get_configuration(): if hasattr(get_configuration, 'configuration'): return get_configuration.configuration - from tools import shared configuration = shared.Configuration(environ=os.environ) get_configuration.configuration = configuration return configuration @@ -453,19 +453,7 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None, } ''' % (sig, i, args, arg_coercions, jsret)) - 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' - asm_setup += ''' -function invoke_%s(%s) { - try { - %sModule["dynCall_%s"](%s); - } catch(e) { - if (typeof e !== 'number' && e !== 'longjmp') throw e; - asm["setThrew"](1, 0); - } -} -''' % (sig, args, 'return ' if sig[0] != 'v' else '', sig, args) + asm_setup += '\n' + shared.JS.make_invoke(sig) + '\n' basic_funcs.append('invoke_%s' % sig) # calculate exports diff --git a/tools/shared.py b/tools/shared.py index 26bb55b3..3e7bac9d 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -1361,6 +1361,20 @@ class JS: return ident.replace('%', '$').replace('@', '_') @staticmethod + def make_invoke(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' + return '''function%s(%s) { + try { + %sModule["dynCall_%s"](%s); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + asm["setThrew"](1, 0); + } +}''' % ((' invoke_' + sig) if named else '', args, 'return ' if sig[0] != 'v' else '', sig, args) + + @staticmethod def align(x, by): while x % by != 0: x += 1 return x |