Skip to content

Comments

WIP: Add preload plugin to compile wasm side modules async#6663

Merged
kripken merged 13 commits intoemscripten-core:incomingfrom
mdboom:async-side-module-loading
Jul 13, 2018
Merged

WIP: Add preload plugin to compile wasm side modules async#6663
kripken merged 13 commits intoemscripten-core:incomingfrom
mdboom:async-side-module-loading

Conversation

@mdboom
Copy link
Contributor

@mdboom mdboom commented Jun 7, 2018

This is a possible solution to #6633 related to dlopen'ing SIDE_MODULES using async wasm compilation (required by Chromium).

This adds a new preload handler for .so and .wasm files to compile them using the async API (WebAssembly.instantiate) at data-loading time. The actual dynamic linking happens synchronously when calling dlopen later. The downside here is that you may end up compiling wasm that never actually gets dlopen'ed, but I think that's probably a domain-specific problem and will be up to the user to resolve, ultimately.

The only change required on the user end is to add --use-preload-plugins when file packaging.

Of note is that loadWebAssemblyModule most be called one at a time, since it sets up an environment in global variables that is later used when the wasm is compiled asynchronously. So this uses a chain of promises to do the compilation, rather than just Promise.all.

This will need tests, obviously, but I thought I'd get feedback on the general approach first.

Copy link
Member

@kripken kripken left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall approach looks good!

Module['preloadPlugins'].push(audioPlugin);

#if WASM
var wasmPlugin = {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please also put this behind the MAIN_MODULE flag, so it's not present in code that doesn't support shared modules.


#if WASM
var wasmPlugin = {};
wasmPlugin['asyncWasmLoadPromise'] = new Promise((resolve, reject) => resolve());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think => is ES6 notation that currently breaks our JS optimizer. Until we fix that, have to use ES5, sorry...

var wasmPlugin = {};
wasmPlugin['asyncWasmLoadPromise'] = new Promise((resolve, reject) => resolve());
wasmPlugin['canHandle'] = function(name) {
return !Module.noWasmDecoding && (name.endsWith('.so') || name.endsWith('.wasm'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is noWasmDecoding?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied the pattern from the audio and image decoders above. It's a way for users to turn off the decoder if desired, I suppose. It might make sense to opt-in rather than opt-out of this, but that would be a change from the other two preload plugins. Happy to change if it makes sense to.


Module["preloadedImages"] = {}; // maps url to image data
Module["preloadedAudios"] = {}; // maps url to audio data
Module["preloadedWasm"] = {}; // maps url to wasm instance exports
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please put this behind the WASM and MAIN_MODULE flags

(also, we should probably put the others behind a flag for preload-plugins, not sure if we have one yet)

src/support.js Outdated
#if WASM
// Loads a side module from binary data
function loadWebAssemblyModule(binary) {
function loadWebAssemblyModule(binary, load_async) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

load_async => loadAsync

@mdboom mdboom force-pushed the async-side-module-loading branch from 93a1f6b to 5a42391 Compare June 18, 2018 15:01
};
Module['preloadPlugins'].push(audioPlugin);

#if WASM && MAIN_MODULE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

our preprocessor is pretty simple, and doesn't support &&... can nest one if inside another.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I think that explains the CI errors)

};
Module['preloadPlugins'].push(audioPlugin);

#if (WASM != 0) && (MAIN_MODULE != 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe this works. Do you see it prevent the code from being included when it should not be?

All I am sure works is

#if WASM
#if MAIN_MODULE
...
#endif
#endif

Sorry about the ugliness, we should improve the preprocessor (which is literally just a few lines of JS at this point)

Copy link
Member

@kripken kripken left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly just minor comments, overall looks nice.

We also need a test for this.

// promises to run in series.
this.asyncWasmLoadPromise = this.asyncWasmLoadPromise.then(
function() {
return Module.loadWebAssemblyModule(byteArray, true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loadWebAssemblyModule should be quoted.

However, does it need to be on Module at all? I think you can just call loadWebAssemblyModule() here.

// loadWebAssemblyModule can not load modules out-of-order, so rather
// than just running the promises in parallel, this makes a chain of
// promises to run in series.
this.asyncWasmLoadPromise = this.asyncWasmLoadPromise.then(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For closure, if a property is quoted once, it must be quoted in all uses, so the two uses on this line must be quoted

// promises to run in series.
this.asyncWasmLoadPromise = this.asyncWasmLoadPromise.then(
function() {
return Module.loadWebAssemblyModule(byteArray, true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also ; at end of line

@mdboom
Copy link
Contributor Author

mdboom commented Jun 28, 2018

Quick question about writing a test. I added a test to test_browser.py to load a side module from the virtual file system in this way, but it's failing with the message:

using preloaded data can only be done on a web page or in a web worker

This is coming from the code that file_packager.py generates to test whether it's in a browser.

I had assumed test_browser.py tests are only run in the browser. Is there a way to flag this test to only run in that context?

@mdboom mdboom force-pushed the async-side-module-loading branch from 778034a to fe094dc Compare June 28, 2018 21:39
@kripken
Copy link
Member

kripken commented Jun 29, 2018

How did you write the test? If you call emcc etc. yourself, it doesn't know it's a browser test (even if it's in test_browser.py) See the btest() method that most browser tests use, and for example test_emscripten_api2, which uses that + the file packager together.

@mdboom
Copy link
Contributor Author

mdboom commented Jun 29, 2018

Thanks for the tip. Making progress. I have a test mostly working (pushed to this PR). It displays the expected output in the browser window, but then hangs for a long time and it seems the test harness doesn't get the output.

======================================================================
ERROR: test_preload_module (test_browser.browser)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/mdboom/Work/builds/compiling/emscripten/tests/test_browser.py", line 2320, in test_preload_module
    self.btest(main, args=['-s', 'MAIN_MODULE=1', '--preload-file', '.@/', '-O2', '-s', 'WASM=1', '--use-preload-plugins'], expected=expected)
  File "/home/mdboom/Work/builds/compiling/emscripten/tests/runner.py", line 1033, in btest
    self.run_browser(outfile + url_suffix, message, ['/report_result?' + e for e in expected], timeout=timeout)
  File "/home/mdboom/Work/builds/compiling/emscripten/tests/runner.py", line 867, in run_browser
    self.assertIdentical(expectedResult, output)
  File "/home/mdboom/Work/builds/compiling/emscripten/tests/runner.py", line 546, in assertIdentical
    limit_size(''.join([a.rstrip()+'\n' for a in difflib.unified_diff(x.split('\n'), y.split('\n'), fromfile='expected', tofile='actual')]))
Exception: Expected to have '/report_result?hello from main
hello from library' == '[no http server activity]', diff:

--- expected
+++ actual
@@ -1,2 +1 @@
-/report_result?hello from main
-hello from library
+[no http server activity]

#endif
}
''')
check_execute([PYTHON, EMCC, 'library.c', '-s', 'SIDE_MODULE=1', '-O2', '-o', 'library.wasm', '-s', 'WASM=1'])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we prefer run_process now for calling python processes

@kripken
Copy link
Member

kripken commented Jun 29, 2018

Ah, another difference is we don't forward stdout/stderr in browser tests. Instead, use the REPORT_RESULT macro to report a result code, see e.g. tests/browser_test_hello_world.c. That code is what btest wants in the expected param.

@mdboom
Copy link
Contributor Author

mdboom commented Jun 30, 2018

Cool. Thanks for the pointers. I think I have something that works now... we'll see how the CI likes it.

@kripken
Copy link
Member

kripken commented Jul 1, 2018

Thanks! Looks good on CI (some other random error there, but doesn't look related).

However, reading the test now, it makes me think maybe a preload plugin on .wasm isn't right. Perhaps this should be on .so files? Or perhaps .wasm.so? Just that .wasm files may not all be shared libraries. OTOH there doesn't seem to be any particular suffix proposed in https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md

@kripken
Copy link
Member

kripken commented Jul 1, 2018

Another thing we should do here is update the docs to mention this. I think we have something about preload-plugins somewhere, but I don't remember offhand.

@mdboom
Copy link
Contributor Author

mdboom commented Jul 10, 2018

wrt file extensions: .so alone would be enough to solve my specific problem. Let me know where you come down and I'm happy to update the PR.

wrt documentation: This is the closest thing I can find in the docs, and even it doesn't go into much detail. Should I write a preloading file section from scratch?

@kripken
Copy link
Member

kripken commented Jul 10, 2018

Ok, let's do .so then.

For docs, yeah - it seems like we don't have a good section on this then. I think the best place to add a subsection is in https://kripken.github.io/emscripten-site/docs/porting/files/packaging_files.html , and please link to it from the place you found, as well as the preloading-related functions mentioned in https://kripken.github.io/emscripten-site/docs/api_reference/emscripten.h.html Thanks!

@mdboom mdboom force-pushed the async-side-module-loading branch from ce3f9bb to 6b79174 Compare July 12, 2018 12:39
@mdboom
Copy link
Contributor Author

mdboom commented Jul 12, 2018

Great. I've made this .so only and updated the docs.

@kripken
Copy link
Member

kripken commented Jul 12, 2018

Looks good, thanks! Just waiting on CI to re-run (was some problem on the browser run, which is important here).

@kripken
Copy link
Member

kripken commented Jul 12, 2018

Actually browser.test_preload_module has failed. Does it pass for you locally?

(There are also 2 emrun-using tests that fail as well, but they are breakage on incoming, should be fixed there now, can ignore those.)

@mdboom
Copy link
Contributor Author

mdboom commented Jul 13, 2018

Ah, the test broke because it was testing a SIDE_MODULE with a .wasm extension, and this was changed to only handle .so. Hopefully fixed now and it's working for me locally.

@kripken
Copy link
Member

kripken commented Jul 13, 2018

Looks good, thanks!

@kripken kripken merged commit a5866a5 into emscripten-core:incoming Jul 13, 2018
@mdboom mdboom mentioned this pull request Jul 25, 2018
navytux added a commit to navytux/emscripten that referenced this pull request Nov 15, 2018
Currently Emscripten allows to create shared libraries (DSO) and link
them to main module. However a shared library itself cannot be linked to
another shared library.

The lack of support for DSO -> DSO linking becomes problematic in cases when
there are several shared libraries that all need to use another should-be
shared functionality, while linking that should-be shared functionality to main
module is not an option for size reasons. My particular use-case is SciPy
support for Pyodide:

	pyodide/pyodide#211,
	pyodide/pyodide#240

where several of `*.so` scipy modules need to link to LAPACK. If we link to
LAPACK statically from all those `*.so` - it just blows up compiled size

	pyodide/pyodide#211 (comment)

and if we link in LAPACK statically to main module, the main module size is
also increased ~2x, which is not an option, since LAPACK functionality is not
needed by every Pyodide user.

This way we are here to add support for DSO -> DSO linking:

1. similarly to how it is already working for main module -> side module
   linking, when building a side module it is now possible to specify

	-s RUNTIME_LINKED_LIBS=[...]

   with list of shared libraries that side module needs to link to.

2. to store that information, for asm.js, similarly to how it is currently
   handled for main module (which always has js part), we transform
   RUNTIME_LINKED_LIBS to

	libModule.dynamicLibraries = [...]

   (see src/preamble_sharedlib.js)

3. for wasm module, in order to store the information about to which libraries
   a module links, we could in theory use "module" attribute in wasm imports.
   However currently emscripten almost always uses just "env" for that "module"
   attribute, e.g.

	(import "env" "abortStackOverflow" (func $fimport$0 (param i32)))
	(import "env" "_ffunc1" (func $fimport$1))
	...

   and this way we have to embed the information about required libraries for
   the dynamic linker somewhere else.

   What I came up with is to extend "dylink" section with information about
   which shared libraries a shared library needs. This is similar to DT_NEEDED
   entries in ELF.

   (see tools/shared.py)

4. then, the dynamic linker (loadDynamicLibrary) is reworked to handle that information:

   - for asm.js, after loading a libModule, we check libModule.dynamicLibraries
     and post-load them recursively. (it would be better to load needed modules
     before the libModule, but for js we currently have to first eval whole
     libModule's code to be able to read .dynamicLibraries)

   - for wasm the needed libraries are loaded before the wasm module in
     question is instantiated.

     (see changes to loadWebAssemblyModule for details)

5. since we also have to teach dlopen() to handle needed libraries, and since dlopen
   was already duplicating loadDynamicLibrary() code in many ways, instead of
   adding more duplication, dlopen is now reworked to use loadDynamicLibrary
   itself.

   This moves functionality to keep track of loaded DSO, their handles,
   refcounts, etc into the dynamic linker itself, with loadDynamicLibrary now
   accepting various flags (global/nodelete) to handle e.g.
   RTLD_LOCAL/RTLD_GLOBAL and RTLD_NODELETE dlopen cases (RTLD_NODELETE
   semantic is needed for initially-linked-in libraries).

   Also, since dlopen was using FS to read libraries, and loadDynamicLibrary was
   previously using Module['read'] and friends, loadDynamicLibrary now also
   accepts fs interface, which if provided, is used as FS-like interface to load
   library data, and if not - native loading capabilities of the environment
   are still used.

   Another aspect related to deduplication is that loadDynamicLibrary now also
   uses preloaded/precompiled wasm modules, that were previously only used by
   dlopen (see a5866a5 "Add preload plugin to compile wasm side modules async
   (emscripten-core#6663)").

   (see changes to dlopen and loadDynamicLibrary)

6. The functionality to asynchronously load dynamic libraries is also
   integrated into loadDynamicLibrary.

   Libraries were asynchronously preloaded for the case when
   Module['readBinary'] is absent (browser, see 3446d2a "preload wasm dynamic
   libraries when we can't load them synchronously").

   Since this codepath was also needed to be taught of DSO -> DSO dependency,
   the most straightforward thing to do was to teach loadDynamicLibrary to do
   its work asynchronously (under flag) and to switch the preloading to use

	loadDynamicLibrary(..., {loadAsync: true})

   (see changes to src/preamble.js and loadDynamicLibrary)

7. A test is added for verifying linking/dlopening a DSO with other needed library.

   browser.test_dynamic_link is also amended to verify linking to DSO with
   dependencies.

With the patch I've made sure that all core tests (including test_dylink_* and
test_dlfcn_*) are passing for asm{0,1,2} and binaryen{0,1,2}.

However since I cannot get full browser tests to pass even on pristine incoming
(1.38.19-2-g77246e0c1 as of today; there are many failures for both Firefox
63.0.1 and Chromium 70.0.3538.67), I did not tried to verify full browser tests
with my patch. Bit I've made sure that

	browser.test_preload_module
	browser.test_dynamic_link

are passing.

"other" kind of tests also do not pass on pristine incoming for me. This
way I did not tried to verify "other" with my patch.

Thanks beforehand,
Kirill

P.S.

This is my first time I do anything with WebAssembly/Emscripten, and only a
second time with JavaScript, so please forgive me if I missed something.

P.P.S.

I can split the patch into smaller steps, if it will help review.

/cc @kripken, @juj, @sbc100, @max99x, @junjihashimoto, @mdboom, @rth
navytux added a commit to navytux/emscripten that referenced this pull request Nov 15, 2018
Currently Emscripten allows to create shared libraries (DSO) and link
them to main module. However a shared library itself cannot be linked to
another shared library.

The lack of support for DSO -> DSO linking becomes problematic in cases when
there are several shared libraries that all need to use another should-be
shared functionality, while linking that should-be shared functionality to main
module is not an option for size reasons. My particular use-case is SciPy
support for Pyodide:

	pyodide/pyodide#211,
	pyodide/pyodide#240

where several of `*.so` scipy modules need to link to LAPACK. If we link to
LAPACK statically from all those `*.so` - it just blows up compiled size

	pyodide/pyodide#211 (comment)

and if we link in LAPACK statically to main module, the main module size is
also increased ~2x, which is not an option, since LAPACK functionality is not
needed by every Pyodide user.

This way we are here to add support for DSO -> DSO linking:

1. similarly to how it is already working for main module -> side module
   linking, when building a side module it is now possible to specify

	-s RUNTIME_LINKED_LIBS=[...]

   with list of shared libraries that side module needs to link to.

2. to store that information, for asm.js, similarly to how it is currently
   handled for main module (which always has js part), we transform
   RUNTIME_LINKED_LIBS to

	libModule.dynamicLibraries = [...]

   (see src/preamble_sharedlib.js)

3. for wasm module, in order to store the information about to which libraries
   a module links, we could in theory use "module" attribute in wasm imports.
   However currently emscripten almost always uses just "env" for that "module"
   attribute, e.g.

	(import "env" "abortStackOverflow" (func $fimport$0 (param i32)))
	(import "env" "_ffunc1" (func $fimport$1))
	...

   and this way we have to embed the information about required libraries for
   the dynamic linker somewhere else.

   What I came up with is to extend "dylink" section with information about
   which shared libraries a shared library needs. This is similar to DT_NEEDED
   entries in ELF.

   (see tools/shared.py)

4. then, the dynamic linker (loadDynamicLibrary) is reworked to handle that information:

   - for asm.js, after loading a libModule, we check libModule.dynamicLibraries
     and post-load them recursively. (it would be better to load needed modules
     before the libModule, but for js we currently have to first eval whole
     libModule's code to be able to read .dynamicLibraries)

   - for wasm the needed libraries are loaded before the wasm module in
     question is instantiated.

     (see changes to loadWebAssemblyModule for details)

5. since we also have to teach dlopen() to handle needed libraries, and since dlopen
   was already duplicating loadDynamicLibrary() code in many ways, instead of
   adding more duplication, dlopen is now reworked to use loadDynamicLibrary
   itself.

   This moves functionality to keep track of loaded DSO, their handles,
   refcounts, etc into the dynamic linker itself, with loadDynamicLibrary now
   accepting various flags (global/nodelete) to handle e.g.
   RTLD_LOCAL/RTLD_GLOBAL and RTLD_NODELETE dlopen cases (RTLD_NODELETE
   semantic is needed for initially-linked-in libraries).

   Also, since dlopen was using FS to read libraries, and loadDynamicLibrary was
   previously using Module['read'] and friends, loadDynamicLibrary now also
   accepts fs interface, which if provided, is used as FS-like interface to load
   library data, and if not - native loading capabilities of the environment
   are still used.

   Another aspect related to deduplication is that loadDynamicLibrary now also
   uses preloaded/precompiled wasm modules, that were previously only used by
   dlopen (see a5866a5 "Add preload plugin to compile wasm side modules async
   (emscripten-core#6663)").

   (see changes to dlopen and loadDynamicLibrary)

6. The functionality to asynchronously load dynamic libraries is also
   integrated into loadDynamicLibrary.

   Libraries were asynchronously preloaded for the case when
   Module['readBinary'] is absent (browser, see 3446d2a "preload wasm dynamic
   libraries when we can't load them synchronously").

   Since this codepath was also needed to be taught of DSO -> DSO dependency,
   the most straightforward thing to do was to teach loadDynamicLibrary to do
   its work asynchronously (under flag) and to switch the preloading to use

	loadDynamicLibrary(..., {loadAsync: true})

   (see changes to src/preamble.js and loadDynamicLibrary)

7. A test is added for verifying linking/dlopening a DSO with other needed library.

   browser.test_dynamic_link is also amended to verify linking to DSO with
   dependencies.

With the patch I've made sure that all core tests (including test_dylink_* and
test_dlfcn_*) are passing for asm{0,1,2} and binaryen{0,1,2}.

However since I cannot get full browser tests to pass even on pristine incoming
(1.38.19-2-g77246e0c1 as of today; there are many failures for both Firefox
63.0.1 and Chromium 70.0.3538.67), I did not tried to verify full browser tests
with my patch. Bit I've made sure that

	browser.test_preload_module
	browser.test_dynamic_link

are passing.

"other" kind of tests also do not pass on pristine incoming for me. This
way I did not tried to verify "other" with my patch.

Thanks beforehand,
Kirill

P.S.

This is my first time I do anything with WebAssembly/Emscripten, and only a
second time with JavaScript, so please forgive me if I missed something.

P.P.S.

I can split the patch into smaller steps, if it will help review.

/cc @kripken, @juj, @sbc100, @max99x, @junjihashimoto, @mdboom, @rth
navytux added a commit to navytux/emscripten that referenced this pull request Nov 16, 2018
Currently dlopen duplicate loadDynamicLibrary in many ways. Since
logic to load dynamic libraries will be soon reworked to support DSO ->
DSO linking, instead of adding more duplication, as a preparatory step
dlopen is first reworked to use loadDynamicLibrary itself.

This moves functionality to keep track of loaded DSO, their handles,
refcounts, etc into the dynamic linker itself, with loadDynamicLibrary now
accepting various flags (global/nodelete) to handle e.g.
RTLD_LOCAL/RTLD_GLOBAL and RTLD_NODELETE dlopen cases (RTLD_NODELETE
semantic is needed for initially-linked-in libraries).

Also, since dlopen was using FS to read libraries, and loadDynamicLibrary was
previously using Module['read'] and friends, loadDynamicLibrary now also
accepts fs interface, which if provided, is used as FS-like interface to load
library data, and if not - native loading capabilities of the environment
are still used.

Another aspect related to deduplication is that loadDynamicLibrary now also
uses preloaded/precompiled wasm modules, that were previously only used by
dlopen (see a5866a5 "Add preload plugin to compile wasm side modules async
(emscripten-core#6663)").
navytux added a commit to navytux/emscripten that referenced this pull request Nov 16, 2018
Currently dlopen duplicate loadDynamicLibrary in many ways. Since
logic to load dynamic libraries will be soon reworked to support DSO ->
DSO linking, instead of adding more duplication, as a preparatory step
dlopen is first reworked to use loadDynamicLibrary itself.

This moves functionality to keep track of loaded DSO, their handles,
refcounts, etc into the dynamic linker itself, with loadDynamicLibrary now
accepting various flags (global/nodelete) to handle e.g.
RTLD_LOCAL/RTLD_GLOBAL and RTLD_NODELETE dlopen cases (RTLD_NODELETE
semantic is needed for initially-linked-in libraries).

Also, since dlopen was using FS to read libraries, and loadDynamicLibrary was
previously using Module['read'] and friends, loadDynamicLibrary now also
accepts fs interface, which if provided, is used as FS-like interface to load
library data, and if not - native loading capabilities of the environment
are still used.

Another aspect related to deduplication is that loadDynamicLibrary now also
uses preloaded/precompiled wasm modules, that were previously only used by
dlopen (see a5866a5 "Add preload plugin to compile wasm side modules async
(emscripten-core#6663)").
navytux added a commit to navytux/emscripten that referenced this pull request Nov 18, 2018
Currently dlopen duplicate loadDynamicLibrary in many ways. Since
logic to load dynamic libraries will be soon reworked to support DSO ->
DSO linking, instead of adding more duplication, as a preparatory step
dlopen is first reworked to use loadDynamicLibrary itself.

This moves functionality to keep track of loaded DSO, their handles,
refcounts, etc into the dynamic linker itself, with loadDynamicLibrary now
accepting various flags (global/nodelete) to handle e.g.
RTLD_LOCAL/RTLD_GLOBAL and RTLD_NODELETE dlopen cases (RTLD_NODELETE
semantic is needed for initially-linked-in libraries).

Also, since dlopen was using FS to read libraries, and loadDynamicLibrary was
previously using Module['read'] and friends, loadDynamicLibrary now also
accepts fs interface, which if provided, is used as FS-like interface to load
library data, and if not - native loading capabilities of the environment
are still used.

Another aspect related to deduplication is that loadDynamicLibrary now also
uses preloaded/precompiled wasm modules, that were previously only used by
dlopen (see a5866a5 "Add preload plugin to compile wasm side modules async
(emscripten-core#6663)").
navytux added a commit to navytux/emscripten that referenced this pull request Nov 20, 2018
Currently dlopen duplicate loadDynamicLibrary in many ways. Since
logic to load dynamic libraries will be soon reworked to support DSO ->
DSO linking, instead of adding more duplication, as a preparatory step
dlopen is first reworked to use loadDynamicLibrary itself.

This moves functionality to keep track of loaded DSO, their handles,
refcounts, etc into the dynamic linker itself, with loadDynamicLibrary now
accepting various flags (global/nodelete) to handle e.g.
RTLD_LOCAL/RTLD_GLOBAL and RTLD_NODELETE dlopen cases (RTLD_NODELETE
semantic is needed for initially-linked-in libraries).

Also, since dlopen was using FS to read libraries, and loadDynamicLibrary was
previously using Module['read'] and friends, loadDynamicLibrary now also
accepts fs interface, which if provided, is used as FS-like interface to load
library data, and if not - native loading capabilities of the environment
are still used.

Another aspect related to deduplication is that loadDynamicLibrary now also
uses preloaded/precompiled wasm modules, that were previously only used by
dlopen (see a5866a5 "Add preload plugin to compile wasm side modules async
(emscripten-core#6663)").
navytux added a commit to navytux/emscripten that referenced this pull request Nov 21, 2018
Currently dlopen duplicate loadDynamicLibrary in many ways. Since
logic to load dynamic libraries will be soon reworked to support DSO ->
DSO linking, instead of adding more duplication, as a preparatory step
dlopen is first reworked to use loadDynamicLibrary itself.

This moves functionality to keep track of loaded DSO, their handles,
refcounts, etc into the dynamic linker itself, with loadDynamicLibrary now
accepting various flags (global/nodelete) to handle e.g.
RTLD_LOCAL/RTLD_GLOBAL and RTLD_NODELETE dlopen cases (RTLD_NODELETE
semantic is needed for initially-linked-in libraries).

Also, since dlopen was using FS to read libraries, and loadDynamicLibrary was
previously using Module['read'] and friends, loadDynamicLibrary now also
accepts fs interface, which if provided, is used as FS-like interface to load
library data, and if not - native loading capabilities of the environment
are still used.

Another aspect related to deduplication is that loadDynamicLibrary now also
uses preloaded/precompiled wasm modules, that were previously only used by
dlopen (see a5866a5 "Add preload plugin to compile wasm side modules async
(emscripten-core#6663)").
navytux added a commit to navytux/emscripten that referenced this pull request Nov 27, 2018
Currently dlopen duplicate loadDynamicLibrary in many ways. Since
logic to load dynamic libraries will be soon reworked to support DSO ->
DSO linking, instead of adding more duplication, as a preparatory step
dlopen is first reworked to use loadDynamicLibrary itself.

This moves functionality to keep track of loaded DSO, their handles,
refcounts, etc into the dynamic linker itself, with loadDynamicLibrary now
accepting various flags (global/nodelete) to handle e.g.
RTLD_LOCAL/RTLD_GLOBAL and RTLD_NODELETE dlopen cases (RTLD_NODELETE
semantic is needed for initially-linked-in libraries).

Also, since dlopen was using FS to read libraries, and loadDynamicLibrary was
previously using Module['read'] and friends, loadDynamicLibrary now also
accepts fs interface, which if provided, is used as FS-like interface to load
library data, and if not - native loading capabilities of the environment
are still used.

Another aspect related to deduplication is that loadDynamicLibrary now also
uses preloaded/precompiled wasm modules, that were previously only used by
dlopen (see a5866a5 "Add preload plugin to compile wasm side modules async
(emscripten-core#6663)").
navytux added a commit to navytux/emscripten that referenced this pull request Nov 29, 2018
Currently dlopen duplicate loadDynamicLibrary in many ways. Since
logic to load dynamic libraries will be soon reworked to support DSO ->
DSO linking, instead of adding more duplication, as a preparatory step
dlopen is first reworked to use loadDynamicLibrary itself.

This moves functionality to keep track of loaded DSO, their handles,
refcounts, etc into the dynamic linker itself, with loadDynamicLibrary now
accepting various flags (global/nodelete) to handle e.g.
RTLD_LOCAL/RTLD_GLOBAL and RTLD_NODELETE dlopen cases (RTLD_NODELETE
semantic is needed for initially-linked-in libraries).

Also, since dlopen was using FS to read libraries, and loadDynamicLibrary was
previously using Module['read'] and friends, loadDynamicLibrary now also
accepts fs interface, which if provided, is used as FS-like interface to load
library data, and if not - native loading capabilities of the environment
are still used.

Another aspect related to deduplication is that loadDynamicLibrary now also
uses preloaded/precompiled wasm modules, that were previously only used by
dlopen (see a5866a5 "Add preload plugin to compile wasm side modules async
(emscripten-core#6663)").
kripken pushed a commit that referenced this pull request Nov 29, 2018
…it (#7571)

Currently dlopen duplicate loadDynamicLibrary in many ways. Since
logic to load dynamic libraries will be soon reworked to support DSO ->
DSO linking, instead of adding more duplication, as a preparatory step
dlopen is first reworked to use loadDynamicLibrary itself.

This moves functionality to keep track of loaded DSO, their handles,
refcounts, etc into the dynamic linker itself, with loadDynamicLibrary now
accepting various flags (global/nodelete) to handle e.g.
RTLD_LOCAL/RTLD_GLOBAL and RTLD_NODELETE dlopen cases (RTLD_NODELETE
semantic is needed for initially-linked-in libraries).

Also, since dlopen was using FS to read libraries, and loadDynamicLibrary was
previously using Module['read'] and friends, loadDynamicLibrary now also
accepts fs interface, which if provided, is used as FS-like interface to load
library data, and if not - native loading capabilities of the environment
are still used.

Another aspect related to deduplication is that loadDynamicLibrary now also
uses preloaded/precompiled wasm modules, that were previously only used by
dlopen (see a5866a5 "Add preload plugin to compile wasm side modules async
(#6663)").
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants