diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-11-15 14:35:30 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-11-15 16:10:23 -0800 |
commit | 813f86354c41cbc49e9ab750d1d795d3a354f71d (patch) | |
tree | 74a37de2595b7d08f48205666ad4e4571e9126d9 | |
parent | 052317d315c17376d99681545ae663821aa732d4 (diff) |
emit libraries and globals in pre phase, which needs to parse globals anyhow, and avoid overhead of libraries in func phases
-rwxr-xr-x | emscripten.py | 28 | ||||
-rw-r--r-- | src/jsifier.js | 53 | ||||
-rw-r--r-- | src/modules.js | 4 | ||||
-rw-r--r-- | src/parseTools.js | 4 | ||||
-rw-r--r-- | tests/cases/gepoverflow.txt | 2 |
5 files changed, 51 insertions, 40 deletions
diff --git a/emscripten.py b/emscripten.py index 91b1de5a..1f6ae2fc 100755 --- a/emscripten.py +++ b/emscripten.py @@ -85,7 +85,6 @@ def emscript(infile, settings, outfile, libraries=[]): pre = [] funcs = [] # split up functions here, for parallelism later meta = [] # needed by each function XXX - post = [] if DEBUG: t = time.time() in_func = False @@ -107,8 +106,7 @@ def emscript(infile, settings, outfile, libraries=[]): elif line.startswith('!'): meta.append(line) # metadata else: - post.append(line) # global - pre.append(line) # pre needs it to, so we know about globals in pre and funcs + pre.append(line) # pre needs it so we know about globals in pre and funcs. So emit globals there ll_lines = None meta = ''.join(meta) if DEBUG and len(meta) > 1024*1024: print >> sys.stderr, 'emscript warning: large amounts of metadata, will slow things down' @@ -120,8 +118,6 @@ def emscript(infile, settings, outfile, libraries=[]): # print >> sys.stderr, '========== funcs ===============\n' # for func in funcs: # print >> sys.stderr, '\n// ===\n\n', ''.join(func) - # print >> sys.stderr, '========== post ==============\n' - # print >> sys.stderr, ''.join(post) # print >> sys.stderr, '=========================\n' # Save settings to a file to work around v8 issue 1579 @@ -135,9 +131,7 @@ def emscript(infile, settings, outfile, libraries=[]): pre_file = temp_files.get('.pre.ll').name open(pre_file, 'w').write(''.join(pre) + '\n' + meta) out = shared.run_js(compiler, shared.COMPILER_ENGINE, [settings_file, pre_file, 'pre'] + libraries, stdout=subprocess.PIPE, cwd=path_from_root('src')) - js, forwarded_data = out.split('//FORWARDED_DATA:') - outfile.write(js) - js = None + pre, forwarded_data = out.split('//FORWARDED_DATA:') forwarded_file = temp_files.get('.json').name open(forwarded_file, 'w').write(forwarded_data) if DEBUG: print >> sys.stderr, ' emscript: phase 1 took %s seconds' % (time.time() - t) @@ -201,23 +195,35 @@ def emscript(infile, settings, outfile, libraries=[]): forwarded_json['Functions']['indexedFunctions'][indexed] = i # make sure not to modify this python object later - we use it in indexize i += 2 forwarded_json['Functions']['nextIndex'] = i + indexing = forwarded_json['Functions']['indexedFunctions'] def indexize(js): return re.sub(r'{{{ FI_([\w\d_$]+) }}}', lambda m: str(indexing[m.groups(0)[0]]), js) - outfile.write(indexize(funcs_js)) + + blockaddrs = forwarded_json['Functions']['blockAddresses'] + def blockaddrsize(js): + return re.sub(r'{{{ BA_([\w\d_$]+)\|([\w\d_$]+) }}}', lambda m: str(blockaddrs[m.groups(0)[0]][m.groups(0)[1]]), js) + + if DEBUG: outfile.write('// pre\n') + outfile.write(blockaddrsize(indexize(pre))) + pre = None + + if DEBUG: outfile.write('// funcs\n') + outfile.write(blockaddrsize(indexize(funcs_js))) funcs_js = None # forward forwarded_data = json.dumps(forwarded_json) forwarded_file = temp_files.get('.2.json').name - open(forwarded_file, 'w').write(forwarded_data) + open(forwarded_file, 'w').write(indexize(forwarded_data)) if DEBUG: print >> sys.stderr, ' emscript: phase 2b took %s seconds' % (time.time() - t) # Phase 3 - post if DEBUG: t = time.time() post_file = temp_files.get('.post.ll').name - open(post_file, 'w').write(''.join(post) + '\n' + meta) + open(post_file, 'w').write('\n') # no input, just processing of forwarded data out = shared.run_js(compiler, shared.COMPILER_ENGINE, [settings_file, post_file, 'post', forwarded_file] + libraries, stdout=subprocess.PIPE, cwd=path_from_root('src')) + if DEBUG: outfile.write('// post\n') outfile.write(indexize(out)) if DEBUG: print >> sys.stderr, ' emscript: phase 3 took %s seconds' % (time.time() - t) diff --git a/src/jsifier.js b/src/jsifier.js index fae92f70..6d3fe781 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -65,24 +65,27 @@ function JSify(data, functionsOnly, givenFunctions) { // Add additional necessary items for the main pass. We can now do this since types are parsed (types can be used through // generateStructInfo in library.js) LibraryManager.load(); - var libFuncsToInclude; - if (INCLUDE_FULL_LIBRARY) { - assert(!BUILD_AS_SHARED_LIB, 'Cannot have both INCLUDE_FULL_LIBRARY and BUILD_AS_SHARED_LIB set.') - libFuncsToInclude = []; - for (var key in LibraryManager.library) { - if (!key.match(/__(deps|postset|inline)$/)) { - libFuncsToInclude.push(key); + + if (phase == 'pre') { + var libFuncsToInclude; + if (INCLUDE_FULL_LIBRARY) { + assert(!BUILD_AS_SHARED_LIB, 'Cannot have both INCLUDE_FULL_LIBRARY and BUILD_AS_SHARED_LIB set.') + libFuncsToInclude = []; + for (var key in LibraryManager.library) { + if (!key.match(/__(deps|postset|inline)$/)) { + libFuncsToInclude.push(key); + } } + } else { + libFuncsToInclude = DEFAULT_LIBRARY_FUNCS_TO_INCLUDE; } - } else { - libFuncsToInclude = DEFAULT_LIBRARY_FUNCS_TO_INCLUDE; - } - libFuncsToInclude.forEach(function(ident) { - data.functionStubs.push({ - intertype: 'functionStub', - ident: '_' + ident + libFuncsToInclude.forEach(function(ident) { + data.functionStubs.push({ + intertype: 'functionStub', + ident: '_' + ident + }); }); - }); + } } // Functions @@ -1279,6 +1282,19 @@ function JSify(data, functionsOnly, givenFunctions) { return; } + // Print out global variables and postsets TODO: batching + if (phase == 'pre') { + legalizedI64s = false; + JSify(analyzer(intertyper(data.unparsedGlobalss[0].lines, true), true), true, Functions); + data.unparsedGlobalss = null; + + var generated = itemsDict.functionStub.concat(itemsDict.GlobalVariablePostSet); + generated.forEach(function(item) { print(indentify(item.JS || '', 2)); }); + } else { + assert(data.unparsedGlobalss[0].lines.length == 0, dump([phase, data.unparsedGlobalss])); + assert(itemsDict.functionStub.length == 0, dump([phase, itemsDict.functionStub])); + } + if (phase == 'pre' || phase == 'funcs') { // serialize out the data that later passes need PassManager.serialize(); // XXX for funcs pass, do not serialize it all. I think we just need which were indexized. @@ -1299,8 +1315,6 @@ function JSify(data, functionsOnly, givenFunctions) { print(read('headless.js').replace("'%s'", "'http://emscripten.org'").replace("'?%s'", "''").replace('%s,', 'null,').replace('%d', '0')); print('}'); } - var generated = itemsDict.functionStub.concat(itemsDict.GlobalVariablePostSet); - generated.forEach(function(item) { print(indentify(item.JS || '', 2)); }); if (RUNTIME_TYPE_INFO) { Types.cleanForRuntime(); print('Runtime.typeInfo = ' + JSON.stringify(Types.types)); @@ -1310,11 +1324,6 @@ function JSify(data, functionsOnly, givenFunctions) { var postParts = processMacros(preprocess(read(postFile))).split('{{GLOBAL_VARS}}'); print(postParts[0]); - // Print out global variables and postsets TODO: batching - legalizedI64s = false; - JSify(analyzer(intertyper(data.unparsedGlobalss[0].lines, true), true), true, Functions); - data.unparsedGlobalss = null; - print(Functions.generateIndexing()); // done last, as it may rely on aliases set in postsets // Load runtime-linked libraries diff --git a/src/modules.js b/src/modules.js index 60b4ff87..1449e3f4 100644 --- a/src/modules.js +++ b/src/modules.js @@ -242,16 +242,14 @@ var Functions = { for (var ident in this.indexedFunctions) { vals[this.indexedFunctions[ident]] = ident; } - // Resolve multi-level aliases all the way down for (var i = 0; i < vals.length; i++) { while (1) { var varData = Variables.globals[vals[i]]; if (!(varData && varData.resolvedAlias)) break; - vals[i] = vals[varData.resolvedAlias]; + vals[i] = vals[+varData.resolvedAlias || eval(varData.resolvedAlias)]; // might need to eval to turn (6) into 6 } } - var indices = vals.toString().replace('"', ''); if (BUILD_AS_SHARED_LIB) { // Shared libraries reuse the parent's function table. diff --git a/src/parseTools.js b/src/parseTools.js index 6a10176c..1205aff5 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1997,9 +1997,7 @@ function parseBlockAddress(segment) { } function finalizeBlockAddress(param) { - assert(param.func in Functions.blockAddresses); - assert(param.label in Functions.blockAddresses[param.func]); - return Functions.blockAddresses[param.func][param.label]; + return '{{{ BA_' + param.func + '|' + param.label + ' }}}'; // something python will replace later } function stripCorrections(param) { diff --git a/tests/cases/gepoverflow.txt b/tests/cases/gepoverflow.txt index 90772c33..bd3091fd 100644 --- a/tests/cases/gepoverflow.txt +++ b/tests/cases/gepoverflow.txt @@ -1,2 +1,2 @@ -*5246502,5247072* +*5246498,5247068* *-514,56* |