aboutsummaryrefslogtreecommitdiff
path: root/tools/shared.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/shared.py')
-rw-r--r--tools/shared.py40
1 files changed, 34 insertions, 6 deletions
diff --git a/tools/shared.py b/tools/shared.py
index 776001cd..d35924c6 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -205,7 +205,7 @@ else:
config_file = '\n'.join(config_file)
# autodetect some default paths
config_file = config_file.replace('{{{ EMSCRIPTEN_ROOT }}}', __rootpath__)
- llvm_root = find_executable('llvm-dis') or '/usr/bin'
+ llvm_root = os.path.dirname(find_executable('llvm-dis') or '/usr/bin/llvm-dis')
config_file = config_file.replace('{{{ LLVM_ROOT }}}', llvm_root)
node = find_executable('node') or find_executable('nodejs') or 'node'
config_file = config_file.replace('{{{ NODE }}}', node)
@@ -400,6 +400,7 @@ EMAR = path_from_root('emar')
EMRANLIB = path_from_root('emranlib')
EMLIBTOOL = path_from_root('emlibtool')
EMCONFIG = path_from_root('em-config')
+EMLINK = path_from_root('emlink.py')
EMMAKEN = path_from_root('tools', 'emmaken.py')
AUTODEBUGGER = path_from_root('tools', 'autodebugger.py')
BINDINGS_GENERATOR = path_from_root('tools', 'bindings_generator.py')
@@ -866,7 +867,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
return generated_libs
@staticmethod
- def link(files, target):
+ def link(files, target, force_archive_contents=False):
actual_files = []
unresolved_symbols = set(['main']) # tracking unresolveds is necessary for .a linking, see below. (and main is always a necessary symbol)
resolved_symbols = set()
@@ -917,7 +918,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
# Link in the .o if it provides symbols, *or* this is a singleton archive (which is apparently an exception in gcc ld)
#print >> sys.stderr, 'need', content, '?', unresolved_symbols, 'and we can supply', new_symbols.defs
#print >> sys.stderr, content, 'DEF', new_symbols.defs, '\n'
- if new_symbols.defs.intersection(unresolved_symbols) or len(files) == 1:
+ if new_symbols.defs.intersection(unresolved_symbols) or len(files) == 1 or force_archive_contents:
if Building.is_bitcode(content):
#print >> sys.stderr, ' adding object', content, '\n'
resolved_symbols = resolved_symbols.union(new_symbols.defs)
@@ -1100,6 +1101,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
@staticmethod
def get_safe_internalize():
+ if not Building.can_build_standalone(): return [] # do not internalize anything
exps = expand_response(Settings.EXPORTED_FUNCTIONS)
if '_malloc' not in exps: exps.append('_malloc') # needed internally, even if user did not add to EXPORTED_FUNCTIONS
exports = ','.join(map(lambda exp: exp[1:], exps))
@@ -1209,8 +1211,8 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
return opts
@staticmethod
- def js_optimizer(filename, passes, jcache, debug):
- return js_optimizer.run(filename, passes, listify(NODE_JS), jcache, debug)
+ def js_optimizer(filename, passes, jcache=False, debug=False, extra_info=None):
+ return js_optimizer.run(filename, passes, listify(NODE_JS), jcache, debug, extra_info)
@staticmethod
def closure_compiler(filename, pretty=True):
@@ -1350,9 +1352,35 @@ JCache = cache.JCache(Cache)
chunkify = cache.chunkify
class JS:
+ memory_initializer_pattern = '/\* memory initializer \*/ allocate\(([\d,\.concat\(\)\[\]\\n ]+)"i8", ALLOC_NONE, ([\dRuntime\.GLOBAL_BASE+]+)\)'
+ no_memory_initializer_pattern = '/\* no memory initializer \*/'
+
+ memory_staticbump_pattern = 'STATICTOP = STATIC_BASE \+ (\d+);'
+
+ global_initializers_pattern = '/\* global initializers \*/ __ATINIT__.push\((.+)\);'
+
@staticmethod
def to_nice_ident(ident): # limited version of the JS function toNiceIdent
- return ident.replace('%', '$').replace('@', '_');
+ 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
# Compression of code and data for smaller downloads
class Compression: