Skip to content

Commit 25071fd

Browse files
committed
Add test for EXPORT_KEEPALIVE
1 parent c288cfa commit 25071fd

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

emscripten.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,8 @@ def install_wrapper(sym):
740740
wrapper = '/** @type {function(...*):?} */\nvar %s = ' % mangled
741741

742742
# TODO(sbc): Can we avoid exporting the dynCall_ functions on the module.
743-
if name.startswith('dynCall_') or (settings.EXPORT_KEEPALIVE and mangled in settings.EXPORTED_FUNCTIONS):
743+
should_export = settings.EXPORT_KEEPALIVE and mangled in settings.EXPORTED_FUNCTIONS
744+
if name.startswith('dynCall_') or should_export:
744745
exported = 'Module["%s"] = ' % mangled
745746
else:
746747
exported = ''
@@ -792,10 +793,10 @@ def create_receiving(exports):
792793
for s in exports_that_are_not_initializers:
793794
mangled = asmjs_mangle(s)
794795
dynCallAssignment = ('dynCalls["' + s.replace('dynCall_', '') + '"] = ') if generate_dyncall_assignment and mangled.startswith('dynCall_') else ''
796+
should_export = settings.EXPORT_ALL or (settings.EXPORT_KEEPALIVE and mangled in settings.EXPORTED_FUNCTIONS)
795797
export_assignment = ''
796-
if settings.MODULARIZE:
797-
if settings.EXPORT_ALL or (settings.EXPORT_KEEPALIVE and mangled in settings.EXPORTED_FUNCTIONS):
798-
export_assignment = f'Module["{mangled}"] = '
798+
if settings.MODULARIZE and should_export:
799+
export_assignment = f'Module["{mangled}"] = '
799800
receiving += [f'{export_assignment}{dynCallAssignment}{mangled} = asm["{s}"]']
800801
else:
801802
receiving += make_export_wrappers(exports, delay_assignment)

test/test_other.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,6 +1307,37 @@ def test_export_all(self):
13071307
self.emcc('lib.c', ['-Oz', '-sEXPORT_ALL', '-sLINKABLE', '--pre-js', 'main.js'], output_filename='a.out.js')
13081308
self.assertContained('libf1\nlibf2\n', self.run_js('a.out.js'))
13091309

1310+
def test_modularize_export_keepalive(self):
1311+
create_file('main.c', r'''
1312+
#include <emscripten.h>
1313+
EMSCRIPTEN_KEEPALIVE int libf1() { return 42; }
1314+
''')
1315+
1316+
# By default, all kept alive functions should be exported.
1317+
self.emcc('main.c', ['-sMODULARIZE=1'], output_filename='test.js')
1318+
1319+
# print(read_file('test.js'))
1320+
1321+
assert ("Module[\"_libf1\"] = " in read_file('test.js'))
1322+
1323+
# Ensures that EXPORT_KEEPALIVE=0 remove the exports
1324+
self.emcc('main.c', ['-sMODULARIZE=1', '-sEXPORT_KEEPALIVE=0'], output_filename='test.js')
1325+
assert (not ("Module[\"_libf1\"] = " in read_file('test.js')))
1326+
1327+
def test_minimal_modularize_export_keepalive(self):
1328+
create_file('main.c', r'''
1329+
#include <emscripten.h>
1330+
EMSCRIPTEN_KEEPALIVE int libf1() { return 42; }
1331+
''')
1332+
1333+
# By default, no symbols should be exported when using MINIMAL_RUNTIME.
1334+
self.emcc('main.c', ['-sMODULARIZE=1', '-sMINIMAL_RUNTIME=2'], output_filename='test.js')
1335+
assert (not ("Module[\"_libf1\"] = " in read_file('test.js')))
1336+
1337+
# Ensures that EXPORT_KEEPALIVE=1 exports the symbols.
1338+
self.emcc('main.c', ['-sMODULARIZE=1', '-sMINIMAL_RUNTIME=2', '-sEXPORT_KEEPALIVE'], output_filename='test.js')
1339+
assert ("Module[\"_libf1\"] = " in read_file('test.js'))
1340+
13101341
def test_minimal_runtime_export_all_modularize(self):
13111342
"""This test ensures that MODULARIZE and EXPORT_ALL work simultaneously.
13121343

0 commit comments

Comments
 (0)