Skip to content

jsifier: Make JS libraries aliases work even when native export exists #19046

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 30, 2023

Conversation

sbc100
Copy link
Collaborator

@sbc100 sbc100 commented Mar 23, 2023

Followup to #19033.

Updating the test_closure_full_js_library to include webgl2 caused a lot of JSC_REFERENCE_BEFORE_DECLARE closure errors.

This is because we had JS aliases who's target was defined both in JS and in native code. In this case the jsifier was choosing not to include the JS version, which in the case of the GL symbols not what we want. I imagine this is why, prior to #19033, we were duplicating the library entries.

This this change JS symbol aliases now force the alias target to be included from the JS library, even in the case that the native code also emits its own version of a symbol.

This happens in the case of pthreads + MAIN_MODULE + OFFSCREEN_FRAMEBUFFER. In this mode webgl2.c defines (and also exports) the entire set of GL library symbols. In this case we still want the emscripten_XX aliases to point to the original JS versions, not the exported native version.

Sadly it looks like we have at testing gap for that particular combination.

@sbc100 sbc100 force-pushed the fix_gl_aliases branch 3 times, most recently from 5bf875a to 07f4985 Compare March 23, 2023 01:57
@sbc100 sbc100 force-pushed the deps_error_checking branch from 6d7c15d to 282bb0a Compare March 23, 2023 05:24
Base automatically changed from deps_error_checking to main March 23, 2023 07:09
@sbc100 sbc100 force-pushed the fix_gl_aliases branch 2 times, most recently from 8ae41e7 to ceb804f Compare March 23, 2023 15:57
@sbc100 sbc100 force-pushed the fix_gl_aliases branch 3 times, most recently from 28fbf6b to 76fe398 Compare March 23, 2023 16:47
@sbc100 sbc100 requested review from kripken and juj March 23, 2023 16:50
@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 23, 2023

An alternative to this PR would be to revert #19033, but I think I like this solution better.

Followup to #19033.

Updating the `test_closure_full_js_library` to include webgl2 caused
a lot of `JSC_REFERENCE_BEFORE_DECLARE` closure errors.

This is because we had JS aliases who's target was defined both in
JS and in native code.  In this case the jsifier was choosing not to
include the JS version, which in the case of the GL symbols not what
we want.  This is why, prior to #19033, we were duplicating the library
entries.

This this change JS symbol aliases now force the alias target to be
included from the JS library, even in the case that the native code
also emits its own version of a symbol.

This happens in the case of pthreads + MAIN_MODULE +
OFFSCREEN_FRAMEBUFFER. In this mode webgl2.c defines (and also exports)
the entire set of GL library symbols.  In this case we still want the
`emscripten_XX` aliases to point to the original JS versions, no the
natively exported version.

Sadly it looks like we have at testing gab for that particular
combination.
@kripken
Copy link
Member

kripken commented Mar 29, 2023

which in the case of the GL symbols not what we want

Can you explain why that isn't what we want? (If a symbol is defined in both JS and C I'd expect us to always want the C version?)

@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 29, 2023

which in the case of the GL symbols not what we want

Can you explain why that isn't what we want? (If a symbol is defined in both JS and C I'd expect us to always want the C version?)

IIRC, in the case of GL we have wrappers in that look like this:

glGetString() {
   // do something then call the original:
   emscripten_glGetString();
}

On the JS side we have:

// Original function
glGetString: function() ...

// Alias of the above.
emscirpten_glGetString: "glGetString"

Normally this is not a problem since the native C/C++ wrapper called glGetString is not even exported, but in the case of MAIN_MODULE=1 we export everything so that linker sees a native and JS version of glGetString.

In this particular case we want the JS alias to point to the JS function, and not the native one. I'm not sure if that we always what we want but it also doesn't seem unreasonable.

@juj
Copy link
Collaborator

juj commented Mar 30, 2023

This all sounds good to me, though didn't check the code in detail.

Btw, I am wondering if we should rename emscripten_gl* function names all to something else, e.g. _js_gl* or similar? The API emscripten_* is used always for public functions, whereas these renamings for the glGetProc* thing and Offscreen Framebuffer are for internal meaning. End users should never be calling any of the emscripten_gl* functions directly/statically.

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.

I see, thanks. lgtm.

Separately from this, it might be worth thinking about simplifying that. One idea might be to reverse the aliasing, that is, make js_glFoo contain the actual JS code, and add an alias from glFoo to js_glFoo. Then native code would implement glFoo and call out to js_glFoo and no alias would be needed in that case, which seem simpler. But possibly I'm forgetting some issue...

@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 30, 2023

I see, thanks. lgtm.

Separately from this, it might be worth thinking about simplifying that. One idea might be to reverse the aliasing, that is, make js_glFoo contain the actual JS code, and add an alias from glFoo to js_glFoo. Then native code would implement glFoo and call out to js_glFoo and no alias would be needed in that case, which seem simpler. But possibly I'm forgetting some issue...

Agreed, I think these are possible simplifications we can do here. I'll add a comment here and we can look into followups.

@sbc100 sbc100 merged commit 3a285cb into main Mar 30, 2023
@sbc100 sbc100 deleted the fix_gl_aliases branch March 30, 2023 23:56
sbc100 added a commit that referenced this pull request Mar 31, 2023
This test was updated in #19046, but went through CI before #19067
landed which made duplicate signatures into a warning.

`glDrawRangeElements` is defined both in `library_glemu.js` and in
`library_webgl2.js` with the former taking precedence because it is
included later.  This change avoid the duplicate definition.
sbc100 added a commit that referenced this pull request Mar 31, 2023
This test was updated in #19046, but went through CI before #19067
landed which made duplicate signatures into a warning.

`glDrawRangeElements` is defined both in `library_glemu.js` and in
`library_webgl2.js` with the former taking precedence because it is
included later.  This change avoid the duplicate definition.
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.

3 participants