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
4 changes: 3 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,9 @@ jobs:
core0.test_esm_integration*
core0.test_pthread_join_and_asyncify
core0.test_async_ccall_promise_jspi*
core0.test_cubescript_jspi"
core0.test_cubescript_jspi
esm_integration.test_fs_js_api*
"
# Run some basic tests with the minimum version of node that we currently
# support in the generated code.
# Keep this in sync with `OLDEST_SUPPORTED_NODE` in `feature_matrix.py`
Expand Down
2 changes: 1 addition & 1 deletion src/shell.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
// can continue to use Module afterwards as well.
#if MODULARIZE
#if MODULARIZE == 'instance'
var Module;
var Module = {};
#else
var Module = moduleArg;
#endif
Expand Down
12 changes: 6 additions & 6 deletions test/fs/test_fs_js_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,19 +240,19 @@ EM_JS(void, test_fs_close, (), {

void test_fs_mknod() {
EM_ASM(
FS.mknod("mknodtest", 0100000 | 0777 /* S_IFREG | S_RWXU | S_RWXG | S_RWXO */);
FS.mknod("mknodtest", 0o100000 | 0o777 /* S_IFREG | S_RWXU | S_RWXG | S_RWXO */);

FS.create("createtest", 0400 /* S_IRUSR */);
FS.create("createtest", 0o400 /* S_IRUSR */);
);
struct stat s;
stat("mknodtest", &s);

assert(S_ISREG(s.st_mode));
assert(s.st_mode & 0777);
assert(s.st_mode & 0o777);

stat("createtest", &s);
assert(S_ISREG(s.st_mode));
assert(s.st_mode & 0400);
assert(s.st_mode & 0o400);

remove("mknodtest");
remove("createtest");
Expand Down Expand Up @@ -382,7 +382,7 @@ void test_fs_mmap() {
void test_fs_mkdirTree() {
EM_ASM(
FS.mkdirTree("/test1/test2/test3"); // Abs path
FS.mkdirTree("/readable", 0400 /* S_IRUSR */);
FS.mkdirTree("/readable", 0o400 /* S_IRUSR */);
);

struct stat s;
Expand All @@ -394,7 +394,7 @@ void test_fs_mkdirTree() {
assert(S_ISDIR(s.st_mode));

assert(stat("/readable", &s) == 0);
assert(s.st_mode & 0400 /* S_IRUSR */);
assert(s.st_mode & 0o400 /* S_IRUSR */);

EM_ASM(
var ex;
Expand Down
1 change: 1 addition & 0 deletions test/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
'wasm64',
'wasm64_v8',
'wasm64_4gb',
'esm_integration',
]

# The default core test mode, used when none is specified
Expand Down
20 changes: 14 additions & 6 deletions test/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,7 @@ def esm_integration(func):

@wraps(func)
def decorated(self, *args, **kwargs):
self.require_node_canary()
self.node_args += ['--experimental-wasm-modules', '--no-warnings']
self.emcc_args += ['-sWASM_ESM_INTEGRATION', '-Wno-experimental']
if self.is_wasm64():
self.skipTest('wasm64 requires wasm export wrappers')
self.setup_esm_integration()
func(self, *args, **kwargs)

return decorated
Expand Down Expand Up @@ -349,6 +345,14 @@ def should_use_closure(self):
prohibited = ('-g', '--profiling')
return all(f not in self.emcc_args for f in prohibited) and any(f in self.emcc_args for f in required)

def setup_esm_integration(self):
self.require_node_canary()
self.node_args += ['--experimental-wasm-modules', '--no-warnings']
self.set_setting('WASM_ESM_INTEGRATION')
self.emcc_args += ['-Wno-experimental']
if self.is_wasm64():
self.skipTest('wasm64 requires wasm export wrappers')

# Use closure in some tests for some additional coverage
def maybe_closure(self):
if '--closure=1' not in self.emcc_args and self.should_use_closure():
Expand Down Expand Up @@ -9644,11 +9648,13 @@ def test_modularize_instance_embind(self):


# Generate tests for everything
def make_run(name, emcc_args, settings=None, env=None,
def make_run(name, emcc_args=None, settings=None, env=None, # noqa
require_v8=False, v8_args=None,
require_node=False, node_args=None,
require_wasm64=False,
init=None):
if emcc_args is None:
emcc_args = {}
if env is None:
env = {}
if settings is None:
Expand Down Expand Up @@ -9777,6 +9783,8 @@ def setUp(self):
bigint = make_run('bigint', emcc_args=['--profiling-funcs'], settings={'WASM_BIGINT': 1},
init=lambda self: shared.node_bigint_flags(self.get_nodejs()))

esm_integration = make_run('esm_integration', init=lambda self: self.setup_esm_integration())

# Add DEFAULT_TO_CXX=0
strict = make_run('strict', emcc_args=[], settings={'STRICT': 1})
strict_js = make_run('strict_js', emcc_args=[], settings={'STRICT_JS': 1})
Expand Down
14 changes: 7 additions & 7 deletions test/unistd/access.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,17 @@ void test_fchmod() {
chmod("fchmodtest", S_IRUGO | S_IWUGO);
struct stat fileStats;
stat("fchmodtest", &fileStats);
int mode = fileStats.st_mode & 0777;
int mode = fileStats.st_mode & 0o777;
// Allow S_IXUGO in addtion to S_IWUGO because on windows
// we always report the execute bit.
assert(mode == (S_IRUGO | S_IWUGO) || mode == (S_IRUGO | S_IWUGO | S_IXUGO));

EM_ASM(
var fchmodstream = FS.open("fchmodtest", "r");
FS.fchmod(fchmodstream.fd, 0777);
FS.fchmod(fchmodstream.fd, 0o777);
);
stat("fchmodtest", &fileStats);
assert((fileStats.st_mode & 0777) == 0777);
assert((fileStats.st_mode & 0o777) == 0o777);
}

void test_lchmod() {
Expand All @@ -61,7 +61,7 @@ void test_lchmod() {
// so skip this part of the test.
EM_ASM(
FS.symlink('writeable', 'symlinkfile');
FS.lchmod('symlinkfile', 0777);
FS.lchmod('symlinkfile', 0o777);
);

struct stat symlinkStats;
Expand All @@ -80,21 +80,21 @@ void test_chmod_errors() {
EM_ASM(
var ex;
try {
FS.chmod("nonexistent", 0777);
FS.chmod("nonexistent", 0o777);
} catch (err) {
ex = err;
}
assert(ex.name === "ErrnoError" && ex.errno === 44 /* ENOENT */);

try {
FS.fchmod(99, 0777);
FS.fchmod(99, 0o777);
} catch (err) {
ex = err;
}
assert(ex.name === "ErrnoError" && ex.errno === 8 /* EBADF */);

try {
FS.lchmod("nonexistent", 0777);
FS.lchmod("nonexistent", 0o777);
} catch (err) {
ex = err;
}
Expand Down
24 changes: 17 additions & 7 deletions tools/emscripten.py
Original file line number Diff line number Diff line change
Expand Up @@ -755,10 +755,15 @@ def create_em_js(metadata):
arg_names = [arg.split()[-1].replace('*', '') for arg in args if arg]
args = ','.join(arg_names)
func = f'function {name}({args}) {body}'
if settings.WASM_ESM_INTEGRATION:
# Like JS library function EM_JS functions are exported at the point of
# declaration in WASM_ESM_INTEGRATION node.
func = f'export {func}'
em_js_funcs.append(func)
if (settings.MAIN_MODULE or settings.ASYNCIFY == 2) and name in metadata.em_js_func_types:
sig = func_type_to_sig(metadata.em_js_func_types[name])
func = func + f'\n{name}.sig = \'{sig}\';'
em_js_funcs.append(func)
sig = f'{name}.sig = \'{sig}\';'
em_js_funcs.append(sig)

return em_js_funcs

Expand Down Expand Up @@ -826,7 +831,10 @@ def create_sending(metadata, library_symbols):

for name in metadata.imports:
if name in metadata.em_js_funcs:
send_items_map[name] = name
# EM_JS functions are exported directly at the declaration site in
# WASM_ESM_INTEGRATION mode.
if not settings.WASM_ESM_INTEGRATION:
send_items_map[name] = name
else:
send_items_map[name] = asmjs_mangle(name)

Expand Down Expand Up @@ -881,16 +889,18 @@ def create_sending(metadata, library_symbols):
return '{\n ' + ',\n '.join(elems) + '\n}'


def create_reexports():
def create_reexports(metadata):
assert settings.WASM_ESM_INTEGRATION
exports = '// Re-export imported wasm functions to the JS entry point. These are user-facing and underscore mangled.\n'
wasm_exports = []
for exp in building.user_requested_exports:
if shared.is_c_symbol(exp):
demangled = shared.demangle_c_symbol_name(exp)
if demangled in settings.WASM_EXPORTS:
if demangled in metadata.em_js_funcs:
wasm_exports.append(f'{demangled} as {exp}')
elif demangled in settings.WASM_EXPORTS:
wasm_exports.append(exp)
if demangled == 'main' and '__main_argc_argv' in settings.WASM_EXPORTS:
elif demangled == 'main' and '__main_argc_argv' in settings.WASM_EXPORTS:
wasm_exports.append('_main')
exports += f"export {{ {', '.join(wasm_exports)} }};\n\n"
return exports
Expand Down Expand Up @@ -1055,7 +1065,7 @@ def create_module(metadata, function_exports, global_exports, tag_exports,librar
module.append(create_pointer_conversion_wrappers(metadata))

if settings.WASM_ESM_INTEGRATION:
module.append(create_reexports())
module.append(create_reexports(metadata))

return module

Expand Down