Skip to content
Open
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
2 changes: 1 addition & 1 deletion src/jsifier.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ function(${args}) {

// if the function was implemented in compiled code, there is no need to
// include the js version
if (WASM_EXPORTS.has(symbol)) {
if (WASM_EXPORTS.has(symbol) && !WASM_IMPORTS.includes(symbol)) {
return;
}

Expand Down
3 changes: 3 additions & 0 deletions src/settings_internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
// underscore.
var WASM_EXPORTS = [];

// List of symbols imported from JavaScript
var WASM_IMPORTS = [];

// An array of all symbols exported from all the side modules specified on the
// command line.
// These are raw symbol names and are not mangled to include the leading
Expand Down
35 changes: 35 additions & 0 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -1607,6 +1607,41 @@ def test_export_all(self):
# Without the `-sEXPORT_ALL` these symbols will not be visible from JS
self.do_runf('main.c', '_libf1 is not defined', assert_returncode=NON_ZERO, cflags=['-Oz', '-sMAIN_MODULE', '--pre-js', 'pre.js'])

def test_export_all_syscall_override(self):
create_file('main.c', r'''
#include "stdio.h"
#include <fcntl.h>

int syscall_openat_orig(int dirfd, intptr_t path, int flags, void* varags)
__attribute__((__import_module__("env"),
__import_name__("__syscall_openat"), __warn_unused_result__));

int __syscall_openat(int dirfd, intptr_t path, int flags, void* varargs) {
printf("__syscall_openat!\n");
return syscall_openat_orig(dirfd, path, flags, varargs);
}

int main() {
int fd = open("a.c", O_RDONLY);
printf("fd: %d\n", fd);
}
''')

self.do_runf('main.c', '__syscall_openat!', cflags=['-sEXPORT_ALL', '-sNODERAWFS'])
self.do_runf('main.c', '__syscall_openat!', cflags=['-sMAIN_MODULE', '-sNODERAWFS'])
self.do_runf('main.c', '__syscall_openat!', cflags=['-O2', '-sEXPORT_ALL', '-sMAIN_MODULE', '-sNODERAWFS'])
self.do_runf('main.c', '__syscall_openat!', cflags=['-sEXPORT_ALL', '-sMAIN_MODULE', '-sNODERAWFS'])

# Test with ES6 module output
self.run_process([EMCC, 'main.c', '-o', 'main.mjs', '-sEXPORT_ALL', '-sMAIN_MODULE', '-sNODERAWFS'])
create_file('run.mjs', '''
import {default as loadModule} from './main.mjs'

await loadModule();
''')

self.assertContained('__syscall_openat!', self.run_js('run.mjs'))

def test_export_keepalive(self):
create_file('main.c', r'''
#include <emscripten.h>
Expand Down
13 changes: 10 additions & 3 deletions tools/emscripten.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,10 @@ def update_settings_glue(wasm_file, metadata, base_metadata):

if base_metadata:
settings.WASM_EXPORTS = base_metadata.all_exports
settings.WASM_IMPORTS = base_metadata.imports
else:
settings.WASM_EXPORTS = metadata.all_exports
settings.WASM_IMPORTS = metadata.imports
settings.HAVE_EM_ASM = bool(settings.MAIN_MODULE or len(metadata.em_asm_consts) != 0)

if settings.MAIN_MODULE and settings.ASYNCIFY == 1:
Expand Down Expand Up @@ -969,7 +971,7 @@ def should_export(sym):
return settings.EXPORT_ALL or (settings.EXPORT_KEEPALIVE and sym in settings.EXPORTED_FUNCTIONS)


def create_receiving(function_exports, other_exports, library_symbols, aliases):
def create_receiving(function_exports, other_exports, library_symbols, aliases, wasm_imports):
generate_dyncall_assignment = 'dynCalls' in library_symbols
receiving = ['\n// Imports from the Wasm binary.']

Expand Down Expand Up @@ -1019,6 +1021,7 @@ def create_receiving(function_exports, other_exports, library_symbols, aliases):
# In debug builds we generate trapping functions in case
# folks try to call/use a reference that was taken before the
# wasm module is available.
wasm_imports_mangled = {asmjs_mangle(s) for s in wasm_imports}
for sym in mangled:
module_export = (settings.MODULARIZE or not settings.MINIMAL_RUNTIME) and should_export(sym) and settings.MODULARIZE != 'instance'
if not js_manipulation.isidentifier(sym) and not module_export:
Expand All @@ -1029,7 +1032,11 @@ def create_receiving(function_exports, other_exports, library_symbols, aliases):
assignment += f" = Module['{sym}']"
else:
assignment = f"Module['{sym}']"
receiving.append(f"{assignment} = makeInvalidEarlyAccess('{sym}');")
# Don't generate early access traps for symbols that are also wasm imports.
if sym in wasm_imports_mangled:
receiving.append(f"{assignment};")
else:
receiving.append(f"{assignment} = makeInvalidEarlyAccess('{sym}');")
else:
# Declare all exports in a single var statement
sep = ',\n '
Expand Down Expand Up @@ -1100,7 +1107,7 @@ def create_receiving(function_exports, other_exports, library_symbols, aliases):

def create_module(metadata, function_exports, other_exports, library_symbols, aliases):
module = []
module.append(create_receiving(function_exports, other_exports, library_symbols, aliases))
module.append(create_receiving(function_exports, other_exports, library_symbols, aliases, metadata.imports))

sending = create_sending(metadata, library_symbols)
if settings.WASM_ESM_INTEGRATION:
Expand Down
Loading