diff options
Diffstat (limited to 'emscripten.py')
-rwxr-xr-x | emscripten.py | 59 |
1 files changed, 40 insertions, 19 deletions
diff --git a/emscripten.py b/emscripten.py index bbc4f76d..c9d8505d 100755 --- a/emscripten.py +++ b/emscripten.py @@ -34,9 +34,13 @@ MIN_CHUNK_SIZE = 1024*1024 MAX_CHUNK_SIZE = float(os.environ.get('EMSCRIPT_MAX_CHUNK_SIZE') or 'inf') # configuring this is just for debugging purposes def process_funcs((i, funcs, meta, settings_file, compiler, forwarded_file, libraries, compiler_engine, temp_files, DEBUG)): - ll = ''.join(funcs) + '\n' + meta funcs_file = temp_files.get('.func_%d.ll' % i).name - open(funcs_file, 'w').write(ll) + f = open(funcs_file, 'w') + f.write(funcs) + funcs = None + f.write('\n') + f.write(meta) + f.close() out = jsrun.run_js( compiler, engine=compiler_engine, @@ -188,6 +192,8 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None, funcs, chunk_size, jcache.get_cachename('emscript_files') if jcache else None) + funcs = None + if jcache: # load chunks from cache where we can # TODO: ignore small chunks cached_outputs = [] @@ -223,6 +229,9 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None, outputs = pool.map(process_funcs, commands, chunksize=1) elif len(chunks) == 1: outputs = [process_funcs(commands[0])] + + commands = None + else: outputs = [] @@ -235,6 +244,8 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None, jcache.set(shortkey, keys, outputs[i]) if out and DEBUG and len(chunks) > 0: print >> sys.stderr, ' saving %d funcchunks to jcache' % len(chunks) + chunks = None + if jcache: outputs += cached_outputs # TODO: preserve order outputs = [output.split('//FORWARDED_DATA:') for output in outputs] @@ -258,8 +269,10 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None, for key in curr_forwarded_json['Functions']['indexedFunctions'].iterkeys(): indexed_functions.add(key) if settings.get('ASM_JS'): + export_bindings = settings['EXPORT_BINDINGS'] for key in curr_forwarded_json['Functions']['implementedFunctions'].iterkeys(): - if key in all_exported_functions: exported_implemented_functions.add(key) + if key in all_exported_functions or (export_bindings and key.startswith('_emscripten_bind')): + exported_implemented_functions.add(key) for key, value in curr_forwarded_json['Functions']['unimplementedFunctions'].iteritems(): forwarded_json['Functions']['unimplementedFunctions'][key] = value @@ -268,7 +281,7 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None, if len(parts) > 1: pre = parts[0] outputs.append([parts[1]]) - funcs_js = ''.join([output[0] for output in outputs]) + funcs_js = [''.join([output[0] for output in outputs])] # this will be a list of things, so we do not do string appending as we add more outputs = None if DEBUG: print >> sys.stderr, ' emscript: phase 2b took %s seconds' % (time.time() - t) @@ -313,6 +326,10 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None, last_forwarded_json = json.loads(last_forwarded_data) if settings.get('ASM_JS'): + post_funcs, post_rest = post.split('// EMSCRIPTEN_END_FUNCS\n') + post = post_rest + funcs_js += ['\n' + post_funcs + '// EMSCRIPTEN_END_FUNCS\n'] + simple = os.environ.get('EMCC_SIMPLE_ASM') class Counter: i = 0 @@ -320,11 +337,12 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None, del last_forwarded_json['Functions']['tables']['pre'] # Find function table calls without function tables generated for them - for use in set(re.findall(r'{{{ FTM_[\w\d_$]+ }}}', funcs_js)): - sig = use[8:len(use)-4] - if sig not in last_forwarded_json['Functions']['tables']: - if DEBUG: print >> sys.stderr, 'add empty function table', sig - last_forwarded_json['Functions']['tables'][sig] = 'var FUNCTION_TABLE_' + sig + ' = [0,0];\n' + for funcs_js_item in funcs_js: + for use in set(re.findall(r'{{{ FTM_[\w\d_$]+ }}}', funcs_js_item)): + sig = use[8:len(use)-4] + if sig not in last_forwarded_json['Functions']['tables']: + if DEBUG: print >> sys.stderr, 'add empty function table', sig + last_forwarded_json['Functions']['tables'][sig] = 'var FUNCTION_TABLE_' + sig + ' = [0,0];\n' def make_table(sig, raw): i = Counter.i @@ -340,7 +358,7 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None, asm_setup = '' maths = ['Math.' + func for func in ['floor', 'abs', 'sqrt', 'pow', 'cos', 'sin', 'tan', 'acos', 'asin', 'atan', 'atan2', 'exp', 'log', 'ceil', 'imul']] fundamentals = ['Math', 'Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint16Array', 'Uint32Array', 'Float32Array', 'Float64Array'] - math_envs = ['Runtime.bitshift64', 'Math.min'] # TODO: move min to maths + math_envs = ['Math.min'] # TODO: move min to maths asm_setup += '\n'.join(['var %s = %s;' % (f.replace('.', '_'), f) for f in math_envs]) basic_funcs = ['abort', 'assert', 'asmPrintInt', 'asmPrintFloat', 'copyTempDouble', 'copyTempFloat'] + [m.replace('.', '_') for m in math_envs] if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE', 'SAFE_HEAP_CLEAR'] @@ -411,9 +429,9 @@ var i64Math_modulo = function(a, b, c, d, e) { i64Math.modulo(a, b, c, d, e) }; # finalize - if DEBUG: print >> sys.stderr, 'asm text sizes', len(funcs_js), len(asm_setup), len(asm_global_vars), len(asm_global_funcs), len(pre_tables), len('\n'.join(function_tables_impls)), len(function_tables_defs.replace('\n', '\n ')), len(exports), len(the_global), len(sending), len(receiving) + if DEBUG: print >> sys.stderr, 'asm text sizes', map(len, funcs_js), len(asm_setup), len(asm_global_vars), len(asm_global_funcs), len(pre_tables), len('\n'.join(function_tables_impls)), len(function_tables_defs.replace('\n', '\n ')), len(exports), len(the_global), len(sending), len(receiving) - funcs_js = ''' + funcs_js = [''' %s function asmPrintInt(x, y) { Module.print('int ' + x + ',' + y);// + ' ' + new Error().stack); @@ -463,7 +481,7 @@ var asm = (function(global, env, buffer) { value = value|0; tempRet%d = value; } -''' % (i, i) for i in range(10)]) + funcs_js + ''' +''' % (i, i) for i in range(10)])] + funcs_js + [''' %s return %s; @@ -474,7 +492,7 @@ var asm = (function(global, env, buffer) { Runtime.stackAlloc = function(size) { return asm.stackAlloc(size) }; Runtime.stackSave = function() { return asm.stackSave() }; Runtime.stackRestore = function(top) { asm.stackRestore(top) }; -''' % (pre_tables + '\n'.join(function_tables_impls) + '\n' + function_tables_defs.replace('\n', '\n '), exports, the_global, sending, receiving) +''' % (pre_tables + '\n'.join(function_tables_impls) + '\n' + function_tables_defs.replace('\n', '\n '), exports, the_global, sending, receiving)] # Set function table masks def function_table_maskize(js): @@ -487,17 +505,20 @@ Runtime.stackRestore = function(top) { asm.stackRestore(top) }; sig = m.groups(0)[0] return masks[sig] return re.sub(r'{{{ FTM_([\w\d_$]+) }}}', lambda m: fix(m), js) # masks[m.groups(0)[0]] - funcs_js = function_table_maskize(funcs_js) + funcs_js = map(function_table_maskize, funcs_js) else: function_tables_defs = '\n'.join([table for table in last_forwarded_json['Functions']['tables'].itervalues()]) outfile.write(function_tables_defs) - funcs_js = ''' + funcs_js = [''' // EMSCRIPTEN_START_FUNCS -''' + funcs_js + ''' +'''] + funcs_js + [''' // EMSCRIPTEN_END_FUNCS -''' +'''] - outfile.write(blockaddrsize(indexize(funcs_js))) + for funcs_js_item in funcs_js: # do this loop carefully to save memory + funcs_js_item = indexize(funcs_js_item) + funcs_js_item = blockaddrsize(funcs_js_item) + outfile.write(funcs_js_item) funcs_js = None outfile.write(indexize(post)) |