@@ -886,9 +886,14 @@ def can_use_await():
886
886
def make_export_wrappers(function_exports):
887
887
assert not settings.MINIMAL_RUNTIME
888
888
889
- wrappers = []
889
+ # When exports are only available asyncronously we generate an extran assignWasmExports
890
+ # function. When they are syncronously available we inline the assignment along
891
+ # with the declaration.
892
+ async_exports = (settings.WASM_ASYNC_COMPILATION and not can_use_await()) or settings.PTHREADS
890
893
891
- def install_wrapper(sym):
894
+ def install_debug_wrapper(sym):
895
+ if not settings.ASSERTIONS:
896
+ return False
892
897
# The emscripten stack functions are called very early (by writeStackCookie) before
893
898
# the runtime is initialized so we can't create these wrappers that check for
894
899
# runtimeInitialized.
@@ -901,38 +906,58 @@ def install_wrapper(sym):
901
906
# TODO: Look into removing these, and improving our robustness around thread termination.
902
907
return sym not in {'__trap', 'pthread_self', '_emscripten_proxy_execute_task_queue'}
903
908
904
- for name, types in function_exports.items():
905
- nargs = len(types.params)
906
- mangled = asmjs_mangle(name)
907
- wrapper = 'var %s = ' % mangled
908
-
909
- # TODO(sbc): Can we avoid exporting the dynCall_ functions on the module.
909
+ def outside_export(mangled):
910
910
should_export = settings.EXPORT_KEEPALIVE and mangled in settings.EXPORTED_FUNCTIONS
911
+ # TODO(sbc): Can we avoid exporting the dynCall_ functions on the module.
911
912
if (name.startswith('dynCall_') and settings.MODULARIZE != 'instance') or should_export:
912
913
if settings.MODULARIZE == 'instance':
913
914
# Update the export declared at the top level.
914
- wrapper += f" __exp_{mangled} = "
915
+ return f" __exp_{mangled}"
915
916
else:
916
- exported = "Module['%s'] = " % mangled
917
- else:
918
- exported = ''
919
- wrapper += exported
920
-
921
- if settings.ASSERTIONS and install_wrapper(name):
922
- # With assertions enabled we create a wrapper that are calls get routed through, for
923
- # the lifetime of the program.
924
- wrapper += f"createExportWrapper('{name}', {nargs});"
925
- elif (settings.WASM_ASYNC_COMPILATION and not can_use_await()) or settings.PTHREADS:
926
- # With WASM_ASYNC_COMPILATION wrapper will replace the global var and Module var on
927
- # first use.
928
- args = [f'a{i}' for i in range(nargs)]
929
- args = ', '.join(args)
930
- wrapper += f"({args}) => ({mangled} = {exported}wasmExports['{name}'])({args});"
931
- else:
932
- wrapper += f"wasmExports['{name}']"
917
+ return "Module['%s']" % mangled
933
918
934
- wrappers.append(wrapper)
935
- return wrappers
919
+ rtn = []
920
+ rtn.append('function assignWasmExports(wasmExports) {')
921
+ for name, types in function_exports.items():
922
+ # If a debug wrapper was used then we don't need to update anything, we want to
923
+ # always use the wrapper, and never the direct export.
924
+ if install_debug_wrapper(name):
925
+ continue
926
+ mangled = asmjs_mangle(name)
927
+ wrapper = f' {mangled} = '
928
+ additional_export = outside_export(mangled)
929
+ if additional_export:
930
+ wrapper += additional_export + ' = '
931
+ wrapper += f"wasmExports['{name}'];"
932
+ rtn.append(wrapper)
933
+
934
+ rtn.append('}')
935
+
936
+ rtn.append('')
937
+ rtn.append('// Exported wasm functions.')
938
+ if async_exports:
939
+ rtn.append('// These are declared here but will be remain undefined until async wasm instanatiation is complete.')
940
+
941
+ if settings.ASSERTIONS:
942
+ for name, types in function_exports.items():
943
+ mangled = asmjs_mangle(name)
944
+ if install_debug_wrapper(name):
945
+ # With assertions enabled we create a wrapper that are calls get routed through, for
946
+ # the lifetime of the program.
947
+ nargs = len(types.params)
948
+ additional_export = outside_export(mangled)
949
+ if additional_export:
950
+ rtn.append(f"var {mangled} = {additional_export} = createExportWrapper('{name}', {nargs});")
951
+ else:
952
+ rtn.append(f"var {mangled} = createExportWrapper('{name}', {nargs});")
953
+ else:
954
+ rtn.append(f'var {mangled};')
955
+ else:
956
+ mangled = [asmjs_mangle(name) for name in function_exports]
957
+ sep = ',\n '
958
+ rtn.append(f'var {sep.join(mangled)};')
959
+
960
+ return rtn
936
961
937
962
938
963
def create_receiving(function_exports):
@@ -986,17 +1011,15 @@ def create_module(receiving, metadata, global_exports, library_symbols):
986
1011
else:
987
1012
module.append('var wasmImports = %s;\n' % sending)
988
1013
1014
+ module.append(receiving)
1015
+
989
1016
if not settings.MINIMAL_RUNTIME:
990
- if settings.WASM_ASYNC_COMPILATION:
991
- if can_use_await():
992
- # In modularize mode the generated code is within a factory function.
993
- module.append("var wasmExports = await createWasm();\n")
994
- else:
995
- module.append("var wasmExports;\ncreateWasm();\n")
1017
+ if settings.WASM_ASYNC_COMPILATION and can_use_await():
1018
+ # In modularize mode the generated code is within a factory function.
1019
+ module.append("var wasmExports = await createWasm();\n")
996
1020
else:
997
- module.append("var wasmExports = createWasm ();\n")
1021
+ module.append("var wasmExports;\ncreateWasm ();\n")
998
1022
999
- module.append(receiving)
1000
1023
if settings.SUPPORT_LONGJMP == 'emscripten' or not settings.DISABLE_EXCEPTION_CATCHING:
1001
1024
module.append(create_invoke_wrappers(metadata))
1002
1025
else:
0 commit comments