Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ Current Trunk
of ccache via emsdk, or from https://github.com/juj/ccache/tree/emscripten,
and run explicitly with "ccache emcc ..." after installing, or automatically
just with "emcc ..." after activating ccache via emsdk (#13498).
- Added support to use a custom set of substitution characters . # and ? to
ease passing arrays of C symbols on the command line to ASYNCIFY_* settings.
(#13477)
- Using EM_ASM and EM_JS in a side module will now result in an error (since
this is not implemented yet). This could effect users were previously
inadvertently including (but not actually using) EM_ASM or EM_JS functions in
Expand Down
13 changes: 13 additions & 0 deletions emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,15 @@ def is_dash_s_for_emcc(args, i):
return arg.isidentifier() and arg.isupper()


def unmangle_symbols_from_cmdline(symbols):
def unmangle(x):
return x.replace('.', ' ').replace('#', '&').replace('?', ',')

if type(symbols) is list:
return [unmangle(x) for x in symbols]
return unmangle(symbols)


def parse_s_args(args):
settings_changes = []
for i in range(len(args)):
Expand Down Expand Up @@ -1459,6 +1468,10 @@ def default_setting(name, new_default):
'_emscripten_stack_get_end',
'_emscripten_stack_set_limits']

shared.Settings.ASYNCIFY_ADD = unmangle_symbols_from_cmdline(shared.Settings.ASYNCIFY_ADD)
shared.Settings.ASYNCIFY_REMOVE = unmangle_symbols_from_cmdline(shared.Settings.ASYNCIFY_REMOVE)
shared.Settings.ASYNCIFY_ONLY = unmangle_symbols_from_cmdline(shared.Settings.ASYNCIFY_ONLY)

# SSEx is implemented on top of SIMD128 instruction set, but do not pass SSE flags to LLVM
# so it won't think about generating native x86 SSE code.
newargs = [x for x in newargs if x not in SIMD_INTEL_FEATURE_TOWER and x not in SIMD_NEON_FLAGS]
Expand Down
17 changes: 17 additions & 0 deletions src/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,7 @@ var ASYNCIFY_STACK_SIZE = 4096;
// to know you got this right), so this is not recommended unless you
// really know what are doing, and need to optimize every bit of speed
// and size.
//
// The names in this list are names from the WebAssembly Names section. The
// wasm backend will emit those names in *human-readable* form instead of
// typical C++ mangling. For example, you should write Struct::func()
Expand All @@ -730,7 +731,23 @@ var ASYNCIFY_STACK_SIZE = 4096;
// changes which would mean a single list couldn't work for both -O0 and -O1
// builds, etc.). You can inspect the wasm binary to look for the actual names,
// either directly or using wasm-objdump or wasm-dis, etc.
//
// Simple '*' wildcard matching is supported.
//
// To avoid dealing with limitations in operating system shells or build system
// escaping, the following substitutions can be made:
// - ' ' -> '.',
// - '&' -> '#',
// - ',' -> '?'.
//
// That is, the function
// "foo(char const*, int&)" can be inputted as
// "foo(char.const*?.int#)" on the command line instead.
//
// Note: Whitespace is part of the function signature! I.e.
// "foo(char const *, int &)" will not match "foo(char const*, int&)", and
// neither would "foo(const char*, int &)".
//
// [link]
var ASYNCIFY_REMOVE = [];

Expand Down
38 changes: 38 additions & 0 deletions tests/browser/test_asyncify_tricky_function_sig.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <stdio.h>
#include <emscripten.h>

volatile int x;

int bar() { return 1; }

__attribute__((noinline))
int foo(const char *str, int &i)
{
if (x == 1337) return bar(); // don't inline me
printf("foo %s\n", str);
emscripten_sleep(1);
printf("foo %d\n", i);
return 42;
}

__attribute__((noinline))
int foo2()
{
if (x == 1337) return bar(); // don't inline me
printf("foo2 1\n");
emscripten_sleep(1);
printf("foo2 2\n");
return 43;
}

int main()
{
printf("main 1\n");
int j = 42;
const char *str = "hello";
int ret = foo(str, j);
printf("main %d\n", ret);
int ret2 = foo2();
printf("ret2 %d\n", ret2);
REPORT_RESULT(ret + ret2);
}
3 changes: 3 additions & 0 deletions tests/test_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3210,6 +3210,9 @@ def test_async(self):
print(opts)
self.btest('browser/async.cpp', '1', args=['-O' + str(opts), '-g2', '-s', 'ASYNCIFY'])

def test_asyncify_tricky_function_sig(self):
self.btest('browser/test_asyncify_tricky_function_sig.cpp', '85', args=['-s', 'ASYNCIFY_ONLY=[foo(char.const*?.int#),foo2(),main,__original_main]', '-s', 'ASYNCIFY=1'])

@requires_threads
def test_async_in_pthread(self):
self.btest('browser/async.cpp', '1', args=['-s', 'ASYNCIFY', '-s', 'USE_PTHREADS', '-s', 'PROXY_TO_PTHREAD', '-g'])
Expand Down