aboutsummaryrefslogtreecommitdiff
path: root/emscripten.py
diff options
context:
space:
mode:
Diffstat (limited to 'emscripten.py')
-rwxr-xr-xemscripten.py66
1 files changed, 40 insertions, 26 deletions
diff --git a/emscripten.py b/emscripten.py
index 40014d2f..ae46ca07 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -793,14 +793,30 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
#if DEBUG: print >> sys.stderr, "META", metadata
#if DEBUG: print >> sys.stderr, "meminit", mem_init
- if DEBUG: logging.debug('emscript: js compiler glue')
+ # function table masks
- # Integrate info from backend
- settings['DEFAULT_LIBRARY_FUNCS_TO_INCLUDE'] = settings['DEFAULT_LIBRARY_FUNCS_TO_INCLUDE'] + metadata['declares']
+ table_sizes = {}
+ for k, v in metadata['tables'].iteritems():
+ table_sizes[k] = str(v.count(',')) # undercounts by one, but that is what we want
+ funcs = re.sub(r"#FM_(\w+)#", lambda m: table_sizes[m.groups(0)[0]], funcs)
+
+ # js compiler
+
+ if DEBUG: logging.debug('emscript: js compiler glue')
# Settings changes
assert settings['TARGET_LE32'] == 1
settings['TARGET_LE32'] = 2
+ if 'i64Add' in metadata['declares']: # TODO: others, once we split them up
+ settings['PRECISE_I64_MATH'] = 2
+ metadata['declares'] = filter(lambda i64_func: i64_func not in ['getHigh32', 'setHigh32', '__muldi3', '__divdi3', '__remdi3', '__udivdi3', '__uremdi3'], metadata['declares']) # FIXME: do these one by one as normal js lib funcs
+
+ # Integrate info from backend
+ settings['DEFAULT_LIBRARY_FUNCS_TO_INCLUDE'] = list(
+ set(settings['DEFAULT_LIBRARY_FUNCS_TO_INCLUDE'] + map(shared.JS.to_nice_ident, metadata['declares'])).difference(
+ map(lambda x: x[1:], metadata['implementedFunctions'])
+ )
+ ) + map(lambda x: x[1:], metadata['externs'])
# Save settings to a file to work around v8 issue 1579
settings_file = temp_files.get('.txt').name
@@ -823,6 +839,10 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
last_forwarded_json = forwarded_json = json.loads(forwarded_data)
+ # merge in information from llvm backend
+
+ last_forwarded_json['Functions']['tables'] = metadata['tables']
+
'''indexed_functions = set()
for key in forwarded_json['Functions']['indexedFunctions'].iterkeys():
indexed_functions.add(key)'''
@@ -831,11 +851,13 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
#print >> sys.stderr, 'glue:', pre, '\n\n||||||||||||||||\n\n', post, '...............'
- # memory initializer
+ # memory and global initializers
+
+ global_initializers = ', '.join(map(lambda i: '{ func: function() { %s() } }' % i, metadata['initializers']))
pre = pre.replace('STATICTOP = STATIC_BASE + 0;', '''STATICTOP = STATIC_BASE + Runtime.alignMemory(%d);
-// /* global initializers */ __ATINIT__.push({ func: function() { runPostSets() } });
-%s''' % (mem_init.count(',')+1, mem_init)) # XXX wrong size calculation!
+/* global initializers */ __ATINIT__.push(%s);
+%s''' % (mem_init.count(',')+1, global_initializers, mem_init)) # XXX wrong size calculation!
funcs_js = [funcs]
if settings.get('ASM_JS'):
@@ -848,6 +870,7 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
# merge forwarded data
assert settings.get('ASM_JS'), 'fastcomp is asm.js only'
+ settings['EXPORTED_FUNCTIONS'] = forwarded_json['EXPORTED_FUNCTIONS']
all_exported_functions = set(settings['EXPORTED_FUNCTIONS']) # both asm.js and otherwise
for additional_export in settings['DEFAULT_LIBRARY_FUNCS_TO_INCLUDE']: # additional functions to export from asm, if they are implemented
all_exported_functions.add('_' + additional_export)
@@ -858,14 +881,6 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
if key in all_exported_functions or export_all or (export_bindings and key.startswith('_emscripten_bind')):
exported_implemented_functions.add(key)
- if settings.get('ASM_JS'):
- # move postsets into the asm module
- class PostSets: js = ''
- def handle_post_sets(m):
- PostSets.js = m.group(0)
- return '\n'
- pre = re.sub(r'function runPostSets[^}]+}', handle_post_sets, pre)
-
#if DEBUG: outfile.write('// pre\n')
outfile.write(pre)
pre = None
@@ -873,25 +888,24 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
#if DEBUG: outfile.write('// funcs\n')
if settings.get('ASM_JS'):
- #print >> sys.stderr, '<<<<<<', post, '>>>>>>'
- post_funcs = '' #, post_rest = post.split('// EMSCRIPTEN_END_FUNCS\n')
- #post = post_rest
-
# Move preAsms to their right place
def move_preasm(m):
contents = m.groups(0)[0]
outfile.write(contents + '\n')
return ''
- post_funcs = re.sub(r'/\* PRE_ASM \*/(.*)\n', lambda m: move_preasm(m), post_funcs)
+ funcs_js[1] = re.sub(r'/\* PRE_ASM \*/(.*)\n', lambda m: move_preasm(m), funcs_js[1])
- funcs_js += ['\n' + post_funcs + '// EMSCRIPTEN_END_FUNCS\n']
+ funcs_js += ['\n// EMSCRIPTEN_END_FUNCS\n']
simple = os.environ.get('EMCC_SIMPLE_ASM')
class Counter:
i = 0
j = 0
- pre_tables = last_forwarded_json['Functions']['tables']['pre']
- del last_forwarded_json['Functions']['tables']['pre']
+ if 'pre' in last_forwarded_json['Functions']['tables']:
+ pre_tables = last_forwarded_json['Functions']['tables']['pre']
+ del last_forwarded_json['Functions']['tables']['pre']
+ else:
+ pre_tables = ''
def make_table(sig, raw):
i = Counter.i
@@ -982,7 +996,7 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
basic_funcs.append('extCall_%s' % sig)
# calculate exports
- exported_implemented_functions = list(exported_implemented_functions)
+ exported_implemented_functions = list(exported_implemented_functions) + metadata['initializers']
exported_implemented_functions.append('runPostSets')
exports = []
if not simple:
@@ -997,8 +1011,8 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
except:
pass
# If no named globals, only need externals
- global_vars = []
- global_funcs = ['_' + key for key, value in forwarded_json['Functions']['libraryFunctions'].iteritems() if value != 2]
+ global_vars = metadata['externs'] #+ forwarded_json['Variables']['globals']
+ global_funcs = list(set(['_' + key for key, value in forwarded_json['Functions']['libraryFunctions'].iteritems() if value != 2]).difference(set(global_vars))) # + metadata['externFuncs']/'declares'
def math_fix(g):
return g if not g.startswith('Math_') else g.split('_')[1]
asm_global_funcs = ''.join([' var ' + g.replace('.', '_') + '=global.' + g + ';\n' for g in maths]) + \
@@ -1101,7 +1115,7 @@ function setTempRet%d(value) {
value = value|0;
tempRet%d = value;
}
-''' % (i, i) for i in range(10)])] + [PostSets.js + '\n'] + funcs_js + ['''
+''' % (i, i) for i in range(10)])] + funcs_js + ['''
%s
return %s;