Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge 19e6a77 into 4fce2cb
Browse files Browse the repository at this point in the history
juj authored Jan 28, 2019

Verified

This commit was signed with the committer’s verified signature. The key has expired.
addaleax Anna Henningsen
2 parents 4fce2cb + 19e6a77 commit 2023042
Showing 2 changed files with 46 additions and 10 deletions.
48 changes: 42 additions & 6 deletions emscripten.py
Original file line number Diff line number Diff line change
@@ -402,6 +402,31 @@ def collapse_redundant_vars(code):
return code


def should_group_global_initializers(initializers):
# If we have at most one global ctor, no need to group global initializers.
# Also in EVAL_CTORS mode, we want to try to evaluate the individual ctor functions, so in that mode,
# do not group ctors into one.
return len(initializers) > 1 and not shared.Settings.EVAL_CTORS


# Each .cpp file with global constructors generates a __GLOBAL__init() function that needs to be
# called to construct the global objects in that compilation unit. This function groups all these
# global initializer functions together into a single globalCtors() function that lives inside the
# asm.js/wasm module, and gets exported out to JS scope to be called at the startup of the application.
def create_global_initializer(initializers):
# If we have no global ctors, don't even generate a dummy empty function to save code space
# Also in EVAL_CTORS mode, we want to try to evaluate the individual ctor functions, so in that mode,
# we do not group ctors into one.
if not should_group_global_initializers(initializers):
return ''

global_initializer = ''' function globalCtors() {
%s
}''' % '\n '.join(i + '();' for i in initializers)

return global_initializer


def create_module_asmjs(function_table_sigs, metadata,
funcs_js, asm_setup, the_global, sending, receiving, asm_global_vars,
asm_global_funcs, pre_tables, final_function_tables, exports):
@@ -428,12 +453,14 @@ def create_module_asmjs(function_table_sigs, metadata,
asm_end = create_asm_end(exports)

asm_variables = collapse_redundant_vars(memory_views + asm_global_vars + asm_temp_vars + asm_runtime_thread_local_vars + '\n' + asm_global_funcs + stack + temp_float + async_state + f0_fround)
asm_global_initializer = create_global_initializer(metadata['initializers'])

module = [
asm_start_pre,
asm_variables,
replace_memory,
start_funcs_marker
start_funcs_marker,
asm_global_initializer
] + runtime_funcs + funcs_js + [
'\n ',
pre_tables, final_function_tables, asm_end,
@@ -690,8 +717,6 @@ def apply_table(js):


def memory_and_global_initializers(pre, metadata, mem_init):
global_initializers = ', '.join('{ func: function() { %s() } }' % i for i in metadata['initializers'])

if shared.Settings.SIMD == 1:
pre = open(path_from_root(os.path.join('src', 'ecmascript_simd.js'))).read() + '\n\n' + pre

@@ -701,8 +726,13 @@ def memory_and_global_initializers(pre, metadata, mem_init):
if shared.Settings.USE_PTHREADS:
pthread = 'if (!ENVIRONMENT_IS_PTHREAD)'

if len(global_initializers) > 0:
global_initializers = '/* global initializers */ {pthread} __ATINIT__.push({global_initializers});'.format(pthread=pthread, global_initializers=global_initializers)
if len(metadata['initializers']) > 0:
if should_group_global_initializers(metadata['initializers']):
global_initializers = '/* global initializers */ %s __ATINIT__.push({ func: function() { globalCtors() } });' % (pthread)
else:
global_initializers = ', '.join('{ func: function() { %s() } }' % i for i in metadata['initializers'])
global_initializers = '/* global initializers */ {pthread} __ATINIT__.push({global_initializers});'.format(pthread=pthread, global_initializers=global_initializers)
else:
else:
global_initializers = '/* global initializers */ /*__ATINIT__.push();*/'

@@ -776,7 +806,13 @@ def get_exported_implemented_functions(all_exported_functions, all_implemented,
if key in all_exported_functions or export_all or (export_bindings and key.startswith('_emscripten_bind')):
funcs.add(key)

funcs = list(funcs) + metadata['initializers']
funcs = list(funcs)
if len(metadata['initializers']) > 0:
if should_group_global_initializers(metadata['initializers']):
funcs += ['globalCtors']
else:
funcs += metadata['initializers']

if not shared.Settings.ONLY_MY_CODE:
if shared.Settings.ALLOW_MEMORY_GROWTH:
funcs.append('_emscripten_replace_memory')
8 changes: 4 additions & 4 deletions tests/test_other.py
Original file line number Diff line number Diff line change
@@ -3654,9 +3654,9 @@ def test_global_inits(self):
src = open('a.out.js').read()
self.assertContained('argc: 1\n16\n17\n10\n', run_js('a.out.js'))
if has_global:
self.assertContained('_GLOBAL_', src)
self.assertContained('globalCtors', src)
else:
self.assertNotContained('_GLOBAL_', src)
self.assertNotContained('globalCtors', src)

def test_implicit_func(self):
create_test_file('src.c', r'''
@@ -7866,9 +7866,9 @@ def test(filename, expectations, size_slack):

print('test on libc++: see effects of emulated function pointers')
test(path_from_root('tests', 'hello_libcxx.cpp'), [
(['-O2'], 35, ['assert'], ['waka'], 196709, 28, 40, 658), # noqa
(['-O2'], 35, ['assert'], ['waka'], 196709, 28, 39, 659), # noqa
(['-O2', '-s', 'EMULATED_FUNCTION_POINTERS=1'],
35, ['assert'], ['waka'], 196709, 28, 21, 619), # noqa
35, ['assert'], ['waka'], 196709, 28, 20, 620), # noqa
], size_slack) # noqa
else:
# wasm-backend

0 comments on commit 2023042

Please sign in to comment.