diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-06-26 10:53:17 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-06-26 10:53:17 -0700 |
commit | 501022cbaa9e63cab9cc218ee0239256945a3061 (patch) | |
tree | fbad1d122eff2e22707552bff81b35fe2df4a621 /emcc | |
parent | 493d0dcf303d66726be5bb08c187f8183ee96a65 (diff) | |
parent | 5383aa8bf93e5c9fed3f67853b2675ab2be10493 (diff) |
Merge branch 'source-maps' of github.com:int3/emscripten into int3-source-maps
Conflicts:
tools/js-optimizer.js
Diffstat (limited to 'emcc')
-rwxr-xr-x | emcc | 77 |
1 files changed, 57 insertions, 20 deletions
@@ -49,7 +49,7 @@ emcc can be influenced by a few environment variables: import os, sys, shutil, tempfile, subprocess, shlex, time, re, logging from subprocess import PIPE, STDOUT -from tools import shared +from tools import shared, jsrun from tools.shared import Compression, execute, suffix, unsuffixed, unsuffixed_basename from tools.response_file import read_response_file @@ -203,10 +203,18 @@ Options that are modified or new in %s include: -g2 Preserve function names -g3 Preserve variable names -g4 Preserve LLVM debug info (if -g was - used when compiling the C/C++ sources) - and show line number debug comments. - This is the highest level of debuggability. - (default in -O0) + used when compiling the C/C++ sources), + show line number debug comments, and + generate source maps. This is the highest + level of debuggability. Note that this + may make -O1 and above significantly + slower because JS optimization will be + limited to 1 core. (default in -O0) + + -g2 Like -g1, but we generate source maps as well, + and we preserve comments even with -O1 and above. + Note that this may be considerably slower because + JS optimization is limited to a single core. --typed-arrays <mode> 0: No typed arrays 1: Parallel typed arrays @@ -731,6 +739,14 @@ try: settings_changes = [] + def validate_arg_level(level_string, max_level, err_msg): + try: + level = int(level_string) + assert 0 <= level <= max_level + except: + raise Exception(err_msg) + return level + for i in range(len(newargs)): newargs[i] = newargs[i].strip() # On Windows Vista (and possibly others), excessive spaces in the command line leak into the items in this array, so trim e.g. 'foo.cpp ' -> 'foo.cpp' if newargs[i].startswith('-O'): @@ -739,11 +755,7 @@ try: if requested_level == 's': requested_level = 2 settings_changes.append('INLINING_LIMIT=50') - try: - opt_level = int(requested_level) - assert 0 <= opt_level <= 3 - except: - raise Exception('Invalid optimization level: ' + newargs[i]) + opt_level = validate_arg_level(requested_level, 3, 'Invalid optimization level: ' + newargs[i]) newargs[i] = '' elif newargs[i].startswith('--llvm-opts'): check_bad_eq(newargs[i]) @@ -787,12 +799,8 @@ try: newargs[i+1] = '' elif newargs[i].startswith('-g'): requested_level = newargs[i][2:] or '3' - try: - debug_level = int(requested_level) - assert 0 <= debug_level <= 4 - except: - raise Exception('Invalid debug level: ' + newargs[i]) - newargs[i] = '-g' # discard level for clang args + debug_level = validate_arg_level(requested_level, 4, 'Invalid debug level: ' + newargs[i]) + newargs[i] = '-g' # we'll need this to get LLVM debug info elif newargs[i] == '--bind': bind = True newargs[i] = '' @@ -885,6 +893,11 @@ try: if opt_level == 0: debug_level = 4 if closure is None and opt_level == 3: closure = True + # TODO: support source maps with js_transform + if js_transform and debug_level >= 4: + logging.warning('disabling source maps because a js transform is being done') + debug_level = 3 + if DEBUG: start_time = time.time() # done after parsing arguments, which might affect debug state if closure: @@ -1409,6 +1422,7 @@ try: # Optimize, if asked to if not LEAVE_INPUTS_RAW: link_opts = [] if debug_level >= 4 else ['-strip-debug'] # remove LLVM debug if we are not asked for it + if llvm_opts > 0: if not os.environ.get('EMCC_OPTIMIZE_NORMALLY'): shared.Building.llvm_opt(in_temp(target_basename + '.bc'), llvm_opts) @@ -1496,9 +1510,11 @@ try: final += '.tr.js' posix = True if not shared.WINDOWS else False logging.debug('applying transform: %s' % js_transform) - execute(shlex.split(js_transform, posix=posix) + [os.path.abspath(final)]) + subprocess.check_call(shlex.split(js_transform, posix=posix) + [os.path.abspath(final)]) if DEBUG: save_intermediate('transformed') + js_transform_tempfiles = [final] + # It is useful to run several js optimizer passes together, to save on unneeded unparsing/reparsing js_optimizer_queue = [] def flush_js_optimizer_queue(): @@ -1508,7 +1524,8 @@ try: if shared.Settings.ASM_JS: js_optimizer_queue = ['asm'] + js_optimizer_queue logging.debug('applying js optimization passes: %s', js_optimizer_queue) - final = shared.Building.js_optimizer(final, js_optimizer_queue, jcache) + final = shared.Building.js_optimizer(final, js_optimizer_queue, jcache, debug_level >= 4) + js_transform_tempfiles.append(final) if DEBUG: save_intermediate('js_opts') else: for name in js_optimizer_queue: @@ -1516,7 +1533,8 @@ try: if shared.Settings.ASM_JS: passes = ['asm'] + passes logging.debug('applying js optimization pass: %s', passes) - final = shared.Building.js_optimizer(final, passes, jcache) + final = shared.Building.js_optimizer(final, passes, jcache, debug_level >= 4) + js_transform_tempfiles.append(final) save_intermediate(name) js_optimizer_queue = [] @@ -1525,7 +1543,8 @@ try: if DEBUG == '2': # Clean up the syntax a bit - final = shared.Building.js_optimizer(final, [], jcache) + final = shared.Building.js_optimizer(final, [], jcache, debug_level >= 4) + js_transform_tempfiles.append(final) if DEBUG: save_intermediate('pretty') def get_eliminate(): @@ -1543,6 +1562,8 @@ try: flush_js_optimizer_queue() logging.debug('running closure') + # no need to add this to js_transform_tempfiles, because closure and + # debug_level > 0 are never simultaneously true final = shared.Building.closure_compiler(final) if DEBUG: save_intermediate('closure') @@ -1590,6 +1611,7 @@ try: src = re.sub('/\* memory initializer \*/ allocate\(([\d,\.concat\(\)\[\]\\n ]+)"i8", ALLOC_NONE, Runtime\.GLOBAL_BASE\)', repl, src, count=1) open(final + '.mem.js', 'w').write(src) final += '.mem.js' + js_transform_tempfiles[-1] = final # simple text substitution preserves comment line number mappings if DEBUG: if os.path.exists(memfile): save_intermediate('meminit') @@ -1597,12 +1619,25 @@ try: else: logging.debug('did not see memory initialization') + def generate_source_map(map_file_base_name, offset=0): + jsrun.run_js(shared.path_from_root('tools', 'source-maps', 'sourcemapper.js'), + shared.NODE_JS, js_transform_tempfiles + + ['--sourceRoot', os.getcwd(), + '--mapFileBaseName', map_file_base_name, + '--offset', str(offset)]) + # If we were asked to also generate HTML, do that if final_suffix == 'html': logging.debug('generating HTML') shell = open(shell_path).read() html = open(target, 'w') if not Compression.on: + if debug_level >= 4: + match = re.match('.*?<script[^>]*>{{{ SCRIPT_CODE }}}</script>', shell, + re.DOTALL) + if match is None: + raise RuntimeError('Could not find script insertion point') + generate_source_map(target, match.group().count('\n')) html.write(shell.replace('{{{ SCRIPT_CODE }}}', open(final).read())) else: # Compress the main code @@ -1673,6 +1708,8 @@ try: from tools.split import split_javascript_file split_javascript_file(final, unsuffixed(target), split_js_file) else: + if debug_level >= 4: generate_source_map(target) + # copy final JS to output shutil.move(final, target) |