aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-11-15 14:35:30 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-11-15 16:10:23 -0800
commit813f86354c41cbc49e9ab750d1d795d3a354f71d (patch)
tree74a37de2595b7d08f48205666ad4e4571e9126d9
parent052317d315c17376d99681545ae663821aa732d4 (diff)
emit libraries and globals in pre phase, which needs to parse globals anyhow, and avoid overhead of libraries in func phases
-rwxr-xr-xemscripten.py28
-rw-r--r--src/jsifier.js53
-rw-r--r--src/modules.js4
-rw-r--r--src/parseTools.js4
-rw-r--r--tests/cases/gepoverflow.txt2
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*