''' Usage: left.js right.js n out.js Given two files with the same function names in them, merges in n functions from the latter from the start, order taken as from the first file. This is useful for bisection: 0 means the left file is the output, and a big enough n means the right file is the output. if left is ok and right shows a bug, then the n where a change occurs shows which function is the culprit. ''' import os, sys, shutil import asm_module, shared, shutil left = sys.argv[1] left_asm = asm_module.AsmModule(left) right = sys.argv[2] right_asm = asm_module.AsmModule(right) n = int(sys.argv[3]) out = sys.argv[4] funcs = list(left_asm.funcs) print 'total funcs:', len(funcs) left_map = left_asm.get_funcs_map() right_map = right_asm.get_funcs_map() n = min(n, len(funcs)) for i in range(n):
# main if __name__ == '__main__': infile = sys.argv[1] outfile = sys.argv[2] force_memfile = sys.argv[3] if len(sys.argv) >= 4 else None extra_blacklist = json.loads(sys.argv[4]) if len(sys.argv) >= 5 else [] BLACKLIST = set(list(BLACKLIST) + extra_blacklist) shared.logging.debug('saving original (non-emterpreted) code to ' + infile + '.orig.js') shutil.copyfile(infile, infile + '.orig.js') # final global functions asm = asm_module.AsmModule(infile) # sanity check on blacklist for func in extra_blacklist: assert func in asm.funcs, 'requested blacklist of %s but it does not exist' % func # decide which functions will be emterpreted, and find which are externally reachable (from outside other emterpreted code; those will need trampolines) emterpreted_funcs = set([ func for func in asm.funcs if func not in BLACKLIST and not func.startswith('dynCall_') ]) tabled_funcs = asm.get_table_funcs() exported_funcs = [func.split(':')[0] for func in asm.exports]
''' Separates out the core asm module out of an emscripten output file. This is useful because it lets you load the asm module first, then the main script, which on some browsers uses less memory ''' import os, sys import asm_module infile = sys.argv[1] asmfile = sys.argv[2] otherfile = sys.argv[3] everything = open(infile).read() module = asm_module.AsmModule(infile).asm_js module = module[module.find('=')+1:] # strip the initial "var asm =" bit, leave just the raw module as a function everything = everything.replace(module, 'Module["asm"]') o = open(asmfile, 'w') o.write('Module["asm"] = ') o.write(module) o.write(';') o.close() o = open(otherfile, 'w') o.write(everything) o.close()
By default it adds a ';' to end the var asm = ... statement. You can add a third param to customize that. If the third param is 'swap-in', it will emit code to swap this asm module in, instead of the default one. XXX this probably doesn't work with closure compiler advanced yet XXX ''' import os, sys import asm_module infile = sys.argv[1] outfile = sys.argv[2] extra = sys.argv[3] if len(sys.argv) >= 4 else ';' if extra == 'swap-in': # we do |var asm = | just like the original codebase, so that gets overridden anyhow (assuming global scripts). extra = r''' (Module.asmGlobalArg, Module.asmLibraryArg, Module['buffer']); // special fixups asm.stackRestore(Module['asm'].stackSave()); // if this fails, make sure the original was built to be swappable (-s SWAPPABLE_ASM_MODULE=1) // Finish swap Module['asm'] = asm; if (Module['onAsmSwap']) Module['onAsmSwap'](); ''' asm = asm_module.AsmModule(infile) open(outfile, 'w').write(asm.asm_js + extra)