Skip to content

Commit

Permalink
Prep for upstream llvm change to main mangling. NFC
Browse files Browse the repository at this point in the history
This change should allow https://reviews.llvm.org/D75277 to land
without breaking emscripten.

In the long run I hope to remove all of this in favor of calling
`_start` from JS, but that can happen later, and could be user-visible
if folks are calling `main` themselves.
  • Loading branch information
sbc100 committed May 30, 2022
1 parent 5def5b8 commit d03e732
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 14 deletions.
3 changes: 3 additions & 0 deletions emcc.py
Expand Up @@ -1724,6 +1724,9 @@ def phase_linker_setup(options, state, newargs, user_settings):
assert not settings.EXPORTED_FUNCTIONS
settings.EXPORTED_FUNCTIONS = ['_main']

if '_main' in settings.EXPORTED_FUNCTIONS:
settings.EXPORTED_FUNCTIONS.append('___main_argc_argv')

if settings.STANDALONE_WASM:
# In STANDALONE_WASM mode we either build a command or a reactor.
# See https://github.com/WebAssembly/WASI/blob/main/design/application-abi.md
Expand Down
13 changes: 11 additions & 2 deletions emscripten.py
Expand Up @@ -297,6 +297,11 @@ def emscript(in_wasm, out_wasm, outfile_js, memfile):

metadata = finalize_wasm(in_wasm, out_wasm, memfile)

if '__main_argc_argv' in metadata['exports']:
settings.MANGLED_MAIN = 1
metadata['exports'].remove('__main_argc_argv')
metadata['exports'].append('main')

update_settings_glue(metadata)

if not settings.WASM_BIGINT and metadata['emJsFuncs']:
Expand Down Expand Up @@ -778,6 +783,8 @@ def make_export_wrappers(exports, delay_assignment):
wrappers = []
for name in exports:
mangled = asmjs_mangle(name)
if settings.MANGLED_MAIN and name == 'main':
name = '__main_argc_argv'
# The emscripten stack functions are called very early (by writeStackCookie) before
# the runtime is initialized so we can't create these wrappers that check for
# runtimeInitialized.
Expand Down Expand Up @@ -817,8 +824,6 @@ def create_receiving(exports):
if not settings.DECLARE_ASM_MODULE_EXPORTS:
return ''

exports_that_are_not_initializers = [x for x in exports if x != building.WASM_CALL_CTORS]

receiving = []

# with WASM_ASYNC_COMPILATION that asm object may not exist at this point in time
Expand All @@ -833,8 +838,12 @@ def create_receiving(exports):
# var asm = output.instance.exports;
# _main = asm["_main"];
generate_dyncall_assignment = settings.DYNCALLS and '$dynCall' in settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE
exports_that_are_not_initializers = [x for x in exports if x != building.WASM_CALL_CTORS]

for s in exports_that_are_not_initializers:
mangled = asmjs_mangle(s)
if settings.MANGLED_MAIN and s == 'main':
s = '__main_argc_argv'
dynCallAssignment = ('dynCalls["' + s.replace('dynCall_', '') + '"] = ') if generate_dyncall_assignment and mangled.startswith('dynCall_') else ''
receiving += [dynCallAssignment + mangled + ' = asm["' + s + '"];']
else:
Expand Down
2 changes: 1 addition & 1 deletion src/library_dylink.js
Expand Up @@ -444,7 +444,7 @@ var LibraryDylink = {

// Export native export on the Module object.
// TODO(sbc): Do all users want this? Should we skip this by default?
var module_sym = asmjsMangle(sym);
var module_sym = asmjsMangle(sym == '__main_argc_argv' ? 'main' : sym);
if (!Module.hasOwnProperty(module_sym)) {
Module[module_sym] = exports[sym];
}
Expand Down
2 changes: 2 additions & 0 deletions src/settings_internal.js
Expand Up @@ -227,3 +227,5 @@ var TRANSPILE_TO_ES5 = false;
// A copy of the default the default INCOMING_MODULE_JS_API. (Soon to
// include additional items).
var ALL_INCOMING_MODULE_JS_API = []

var MANGLED_MAIN = false;
16 changes: 6 additions & 10 deletions system/lib/standalone/__main_argc_argv.c
Expand Up @@ -5,17 +5,13 @@
* found in the LICENSE file.
*/

// This file should no longer be needed once we land the llvm-side change to
// switch to using __main_argc_argv:
// TODO(https://reviews.llvm.org/D75277)

// See https://github.com/CraneStation/wasi-libc/pull/152

#include <assert.h>

int main(int argc, char *argv[]);
// New compilers define `__main_argc_argv`. If that doesn't exist, we
// may get called here. Old compilers define `main` expecting an
// argv/argc, so call that.
// TODO: Remove this layer when we no longer have to support old compilers.
int __legacy_main(int argc, char *argv[]) __asm("main");

__attribute__((__weak__))
int __main_argc_argv(int argc, char *argv[]) {
return main(argc, argv);
return __legacy_main(argc, argv);
}
2 changes: 1 addition & 1 deletion tools/building.py
Expand Up @@ -233,7 +233,7 @@ def llvm_backend_args():
# When 'main' has a non-standard signature, LLVM outlines its content out to
# '__original_main'. So we add it to the allowed list as well.
if 'main' in settings.EXCEPTION_CATCHING_ALLOWED:
settings.EXCEPTION_CATCHING_ALLOWED += ['__original_main']
settings.EXCEPTION_CATCHING_ALLOWED += ['__original_main', '__main_argc_argv']
allowed = ','.join(settings.EXCEPTION_CATCHING_ALLOWED)
args += ['-emscripten-cxx-exceptions-allowed=' + allowed]

Expand Down

0 comments on commit d03e732

Please sign in to comment.