Skip to content

Commit

Permalink
Merge 19e6a77 into 4fce2cb
Browse files Browse the repository at this point in the history
  • Loading branch information
juj authored Jan 28, 2019
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.