aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--emlink.py23
-rwxr-xr-xtests/runner.py14
-rw-r--r--tools/shared.py2
3 files changed, 37 insertions, 2 deletions
diff --git a/emlink.py b/emlink.py
index c8bee707..dc167b03 100644
--- a/emlink.py
+++ b/emlink.py
@@ -55,6 +55,15 @@ class AsmModule():
self.mem_init_size = 0
#print >> sys.stderr, self.mem_init_js
+ # global initializers
+ global_inits = re.search(shared.JS.global_initializers_pattern, self.pre_js)
+ if global_inits:
+ self.global_inits_js = global_inits.group(0)
+ self.global_inits = map(lambda init: init.split('{')[2][1:].split('(')[0], global_inits.groups(0)[0].split(','))
+ else:
+ self.global_inits_js = ''
+ self.global_inits = []
+
# 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)]
@@ -87,8 +96,6 @@ class AsmModule():
main.pre_js = re.sub(shared.JS.memory_initializer_pattern if main.mem_init_js else shared.JS.no_memory_initializer_pattern, full_allocation, main.pre_js, count=1)
main.pre_js = re.sub('STATICTOP = STATIC_BASE \+ (\d+);', 'STATICTOP = STATIC_BASE + %d' % (main.mem_init_size + side.mem_init_size), main.pre_js, count=1)
- # global initializers TODO
-
# imports
main_imports = set(main.imports)
new_imports = [imp for imp in self.imports if imp not in main_imports]
@@ -113,6 +120,18 @@ class AsmModule():
shared.try_delete(temp)
main.extra_funcs_js = relocated_funcs.funcs_js.replace(js_optimizer.start_funcs_marker, '\n')
+ # global initializers
+ if self.global_inits:
+ # TODO: take into account function name replacements
+ all_global_inits = map(lambda init: '{ func: function() { %s() } }' % init, main.global_inits + self.global_inits)
+ all_global_inits_js = '/* global initializers */ __ATINIT__.push(' + ','.join(all_global_inits) + ');'
+ if main.global_inits:
+ target = main.global_inits_js
+ else:
+ target = '// === Body ===\n'
+ all_global_inits_js = target + all_global_inits_js
+ main.pre_js = main.pre_js.replace(target, all_global_inits_js)
+
# tables TODO
# exports
diff --git a/tests/runner.py b/tests/runner.py
index 8944f621..3bd39036 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -10654,6 +10654,20 @@ f.close()
void sidey() { printf("hello from side\n"); }
''', 'hello from main\nhello from side\n')
+ # Global initializer
+ test('global init', '', r'''
+ #include <stdio.h>
+ struct Class {
+ Class() { printf("a new Class\n"); }
+ };
+ static Class c;
+ int main() {
+ return 0;
+ }
+ ''', r'''
+ void nothing() {}
+ ''', 'a new Class\n')
+
def test_symlink(self):
if os.name == 'nt':
return self.skip('Windows FS does not need to be tested for symlinks support, since it does not have them.')
diff --git a/tools/shared.py b/tools/shared.py
index 1d70fcab..26bb55b3 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -1354,6 +1354,8 @@ class JS:
memory_initializer_pattern = '/\* memory initializer \*/ allocate\(([\d,\.concat\(\)\[\]\\n ]+)"i8", ALLOC_NONE, Runtime\.GLOBAL_BASE\)'
no_memory_initializer_pattern = '/\* no memory initializer \*/'
+ global_initializers_pattern = '/\* global initializers \*/ __ATINIT__.push\((.+)\);'
+
@staticmethod
def to_nice_ident(ident): # limited version of the JS function toNiceIdent
return ident.replace('%', '$').replace('@', '_')