diff options
-rw-r--r-- | emlink.py | 31 | ||||
-rw-r--r-- | src/parseTools.js | 7 | ||||
-rwxr-xr-x | tests/runner.py | 2 | ||||
-rw-r--r-- | tools/js-optimizer.js | 2 | ||||
-rw-r--r-- | tools/shared.py | 8 |
5 files changed, 43 insertions, 7 deletions
@@ -12,7 +12,7 @@ Note that the output file can be used as a main module, so you can link multiple side modules into a main module that way. ''' -import os, subprocess, sys +import os, subprocess, sys, re from tools import shared from tools import js_optimizer @@ -36,6 +36,19 @@ class AsmModule(): self.end_funcs = self.js.rfind(js_optimizer.end_funcs_marker) self.end_asm = self.js.rfind(js_optimizer.end_asm_marker) + self.pre = self.js[:self.start_asm] + + # heap initializer + mem_init = re.search(shared.JS.memory_initializer_pattern, self.pre) + if mem_init: + self.mem_init_full_js = mem_init.group(0) + self.mem_init_js = mem_init.groups(0)[0][:-2] + self.mem_init_size = self.mem_init_js.count(',') + self.mem_init_js.count('concat') # XXX add testing for large and small ones + else: + self.mem_init_js = '' + self.mem_init_size = 0 + #print >> sys.stderr, self.mem_init_js + # imports self.imports_js = self.js[self.start_asm:self.start_funcs] self.imports = [m.group(0) for m in js_optimizer.import_sig.finditer(self.imports_js)] @@ -54,9 +67,14 @@ class AsmModule(): def relocate_into(self, main): # heap initializer TODO + concat = '.concat(' if main.mem_init_js and self.mem_init_js else '' + end = ')' if main.mem_init_js and self.mem_init_js else '' + allocation = main.mem_init_js + concat + self.mem_init_js + end + if allocation: + full_allocation = '/* memory initializer */ allocate(' + allocation + ', "i8", ALLOC_NONE, Runtime.GLOBAL_BASE)' + main.pre = re.sub(shared.JS.memory_initializer_pattern if main.mem_init_js else shared.JS.no_memory_initializer_pattern, full_allocation, main.pre, count=1) # global initializers TODO - shared.JS.memory_initializer_pattern # imports main_imports = set(main.imports) @@ -72,7 +90,12 @@ class AsmModule(): rep += '_' replacements[func] = rep - temp = shared.Building.js_optimizer(self.filename, ['asm', 'relocate'], extra_info={ 'replacements': replacements }) + temp = shared.Building.js_optimizer(self.filename, ['asm', 'relocate'], extra_info={ + 'replacements': replacements, + 'fBase': 0, + 'hBase': shared.JS.align(main.mem_init_size, 8) + }) + #print >> sys.stderr, 'relocated side into', temp relocated_funcs = AsmModule(temp) shared.try_delete(temp) main.extra_funcs_js = relocated_funcs.funcs_js.replace(js_optimizer.start_funcs_marker, '\n') @@ -83,7 +106,7 @@ class AsmModule(): def write(self, out): f = open(out, 'w') - f.write(self.js[:self.start_asm]) + f.write(self.pre) f.write(self.imports_js) f.write(self.funcs_js) f.write(self.extra_funcs_js) diff --git a/src/parseTools.js b/src/parseTools.js index 6bc0b7ea..2b143697 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -492,7 +492,9 @@ function makeGlobalUse(ident) { UNINDEXABLE_GLOBALS[ident] = 1; return ident; } - return (Runtime.GLOBAL_BASE + index).toString(); + var ret = (Runtime.GLOBAL_BASE + index).toString(); + if (SIDE_MODULE) ret = '(H_BASE+' + ret + ')'; + return ret; } return ident; } @@ -1627,6 +1629,9 @@ function makePointer(slab, pos, allocator, type, ptr, finalMemoryInitialization) // writing out into memory, without a normal allocation. We put all of these into a single big chunk. assert(typeof slab == 'object'); assert(slab.length % QUANTUM_SIZE == 0, slab.length); // must be aligned already + if (SIDE_MODULE && typeof ptr == 'string') { + ptr = parseInt(ptr.substring(ptr.indexOf('+'), ptr.length-1)); // parse into (H_BASE+X) + } var offset = ptr - Runtime.GLOBAL_BASE; for (var i = 0; i < slab.length; i++) { memoryInitialization[offset + i] = slab[i]; diff --git a/tests/runner.py b/tests/runner.py index 9afc36d3..7a8ccf6f 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -10611,6 +10611,7 @@ f.close() def test_static_link(self): def test(main, side, first=True): + #t = main ; main = side ; side = t open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(main) open(os.path.join(self.get_dir(), 'side.cpp'), 'w').write(side) Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'side.cpp'), '-o', 'side.js', '-s', 'SIDE_MODULE=1', '-O2']).communicate() @@ -10621,6 +10622,7 @@ f.close() out = run_js('together.js', engine=SPIDERMONKEY_ENGINE, stderr=PIPE, full_output=True) self.assertContained('side says 11.', out) self.validate_asmjs(out) + #if first: test(side, main, False) # test reverse order test(''' #include <stdio.h> diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 85171a02..f382496f 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -2760,7 +2760,7 @@ function relocate(ast) { } else if (node[2][1] == 'H_BASE') { base = hBase; } - if (base) { + if (base !== null) { var other = node[3]; if (other[0] == 'num') { other[1] += base; diff --git a/tools/shared.py b/tools/shared.py index bc1177b2..1d70fcab 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -1352,10 +1352,16 @@ chunkify = cache.chunkify class JS: memory_initializer_pattern = '/\* memory initializer \*/ allocate\(([\d,\.concat\(\)\[\]\\n ]+)"i8", ALLOC_NONE, Runtime\.GLOBAL_BASE\)' + no_memory_initializer_pattern = '/\* no memory initializer \*/' @staticmethod def to_nice_ident(ident): # limited version of the JS function toNiceIdent - return ident.replace('%', '$').replace('@', '_'); + return ident.replace('%', '$').replace('@', '_') + + @staticmethod + def align(x, by): + while x % by != 0: x += 1 + return x # Compression of code and data for smaller downloads class Compression: |