diff options
Diffstat (limited to 'emscripten.py')
-rwxr-xr-x | emscripten.py | 57 |
1 files changed, 38 insertions, 19 deletions
diff --git a/emscripten.py b/emscripten.py index bd6994fa..6e5f1e7c 100755 --- a/emscripten.py +++ b/emscripten.py @@ -94,25 +94,27 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None, # Split input into the relevant parts for each phase pre = [] funcs = [] # split up functions here, for parallelism later - func_idents = [] meta = [] # needed by each function XXX if DEBUG: t = time.time() in_func = False ll_lines = open(infile).readlines() + curr_func = None for line in ll_lines: if in_func: - funcs[-1][1].append(line) + curr_func.append(line) if line.startswith('}'): in_func = False - funcs[-1] = (funcs[-1][0], ''.join(funcs[-1][1])) - pre.append(line) # pre needs it to, so we know about all implemented functions + funcs.append((curr_func[0], ''.join(curr_func))) # use the entire line as the identifier + # pre needs to know about all implemented functions, even for non-pre func + pre.append(curr_func[0]) + pre.append(line) + curr_func = None else: if line.startswith(';'): continue if line.startswith('define '): in_func = True - funcs.append((line, [line])) # use the entire line as the identifier - pre.append(line) # pre needs it to, so we know about all implemented functions + curr_func = [line] elif line.find(' = type { ') > 0: pre.append(line) # type elif line.startswith('!'): @@ -224,10 +226,10 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None, # TODO: minimize size of forwarded data from funcs to what we actually need - if cores == 1 and total_ll_size < MAX_CHUNK_SIZE: - assert len(chunks) == 1, 'no point in splitting up without multiple cores' - if len(chunks) > 0: + if cores == 1 and total_ll_size < MAX_CHUNK_SIZE: + assert len(chunks) == 1, 'no point in splitting up without multiple cores' + if DEBUG: print >> sys.stderr, ' emscript: phase 2 working on %d chunks %s (intended chunk size: %.2f MB, meta: %.2f MB, forwarded: %.2f MB, total: %.2f MB)' % (len(chunks), ('using %d cores' % cores) if len(chunks) > 1 else '', chunk_size/(1024*1024.), len(meta)/(1024*1024.), len(forwarded_data)/(1024*1024.), total_ll_size/(1024*1024.)) commands = [ @@ -346,6 +348,14 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None, if settings.get('ASM_JS'): 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 += ['\n' + post_funcs + '// EMSCRIPTEN_END_FUNCS\n'] simple = os.environ.get('EMCC_SIMPLE_ASM') @@ -383,15 +393,12 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None, if settings['CHECK_HEAP_ALIGN']: basic_funcs += ['CHECK_ALIGN_2', 'CHECK_ALIGN_4', 'CHECK_ALIGN_8'] basic_vars = ['STACKTOP', 'STACK_MAX', 'tempDoublePtr', 'ABORT'] basic_float_vars = ['NaN', 'Infinity'] - if forwarded_json['Types']['preciseI64MathUsed']: - basic_funcs += ['i64Math_' + op for op in ['add', 'subtract', 'multiply', 'divide', 'modulo']] - asm_setup += ''' -var i64Math_add = function(a, b, c, d) { i64Math.add(a, b, c, d) }; -var i64Math_subtract = function(a, b, c, d) { i64Math.subtract(a, b, c, d) }; -var i64Math_multiply = function(a, b, c, d) { i64Math.multiply(a, b, c, d) }; -var i64Math_divide = function(a, b, c, d, e) { i64Math.divide(a, b, c, d, e) }; -var i64Math_modulo = function(a, b, c, d, e) { i64Math.modulo(a, b, c, d, e) }; -''' + + if forwarded_json['Types']['preciseI64MathUsed'] or \ + forwarded_json['Functions']['libraryFunctions'].get('llvm_cttz_i32') or \ + forwarded_json['Functions']['libraryFunctions'].get('llvm_ctlz_i32'): + basic_vars += ['cttz_i8', 'ctlz_i8'] + asm_runtime_funcs = ['stackAlloc', 'stackSave', 'stackRestore', 'setThrew'] + ['setTempRet%d' % i for i in range(10)] # function tables def asm_coerce(value, sig): @@ -412,6 +419,18 @@ var i64Math_modulo = function(a, b, c, d, e) { i64Math.modulo(a, b, c, d, e) }; %s; } ''' % (sig, ',' if len(sig) > 1 else '', args, arg_coercions, ret)) + args = ','.join(['a' + str(i) for i in range(1, len(sig))]) + args = 'index' + (',' if args else '') + args + asm_setup += ''' +function invoke_%s(%s) { + try { + %sModule.dynCall_%s(%s); + } catch(e) { + asm.setThrew(1); + } +} +''' % (sig, args, 'return ' if sig[0] != 'v' else '', sig, args) + basic_funcs.append('invoke_%s' % sig) # calculate exports exported_implemented_functions = list(exported_implemented_functions) @@ -429,7 +448,7 @@ var i64Math_modulo = function(a, b, c, d, e) { i64Math.modulo(a, b, c, d, e) }; pass # If no named globals, only need externals global_vars = map(lambda g: g['name'], filter(lambda g: settings['NAMED_GLOBALS'] or g.get('external') or g.get('unIndexable'), forwarded_json['Variables']['globals'].values())) - global_funcs = ['_' + x for x in forwarded_json['Functions']['libraryFunctions'].keys()] + global_funcs = ['_' + key for key, value in forwarded_json['Functions']['libraryFunctions'].iteritems() if value != 2] 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]) + \ |