Skip to content

freetype port: add variant for standardized Wasm EH (WASM_LEGACY_EXCEPTIONS=0)#26729

Open
leehyeonseop wants to merge 5 commits intoemscripten-core:mainfrom
leehyeonseop:fix/freetype-port-new-eh
Open

freetype port: add variant for standardized Wasm EH (WASM_LEGACY_EXCEPTIONS=0)#26729
leehyeonseop wants to merge 5 commits intoemscripten-core:mainfrom
leehyeonseop:fix/freetype-port-new-eh

Conversation

@leehyeonseop
Copy link
Copy Markdown

Summary

The freetype port's SUPPORT_LONGJMP=wasm variant (freetype-legacysjlj) hardcodes WASM_LEGACY_EXCEPTIONS: 1, forcing legacy exception handling instructions. Projects using standardized Wasm EH (-fwasm-exceptions -sWASM_LEGACY_EXCEPTIONS=0 -sSUPPORT_LONGJMP=wasm) cannot link with this port without hitting:

WebAssembly.instantiate(): Compiling function failed:
module uses a mix of legacy and new exception handling instructions

Changes

  • Add a new variant freetype-wasmsjlj with WASM_LEGACY_EXCEPTIONS: 0
  • Update get_lib_name() to return libfreetype-wasmsjlj.a when SUPPORT_LONGJMP=wasm and WASM_LEGACY_EXCEPTIONS=0
  • Append -fwasm-exceptions and -sWASM_LEGACY_EXCEPTIONS=0 to build flags for the new variant

Reproduction

# CMakeLists.txt (Emscripten project)
target_link_options(myapp PUBLIC
  "SHELL:-fwasm-exceptions"
  "SHELL:-sWASM_LEGACY_EXCEPTIONS=0"
  "SHELL:-sSUPPORT_LONGJMP=wasm"
  "SHELL:-sUSE_FREETYPE=1"
)

The existing freetype-legacysjlj variant and its behavior are unchanged. Other ports with similar WASM_LEGACY_EXCEPTIONS: 1 hardcoding (e.g. harfbuzz, sdl2_ttf) may need the same treatment in follow-up PRs.

@sbc100
Copy link
Copy Markdown
Collaborator

sbc100 commented Apr 20, 2026

You you update the test_freetype test in test_other such that it triggers the issue this fixes. It does look like do currently build this configuration:

$ ./test/runner other.test_freetype* -v
using verbose test runner (verbose output requested)
Running 4 tests
Using 4 parallel test processes
[1/4] test_freetype_with_pthreads (test_other.other.test_freetype_with_pthreads) ... ok
[2/4] test_freetype_wasm (test_other.other.test_freetype_wasm) ... ok
[3/4] test_freetype_wasm_legacy (test_other.other.test_freetype_wasm_legacy) ... ok
[4/4] test_freetype_emscripten (test_other.other.test_freetype_emscripten) ... ok

Verify that the correct port variant (libfreetype-wasmsjlj.a) is
selected when building with -fwasm-exceptions -sWASM_LEGACY_EXCEPTIONS=0
-sSUPPORT_LONGJMP=wasm.  Without the fix, libfreetype-legacysjlj.a is
used instead, producing a binary with mixed legacy and new EH
instructions that fails at instantiation time in browsers.
@leehyeonseop
Copy link
Copy Markdown
Author

You you update the test_freetype test in test_other such that it triggers the issue this fixes. It does look like do currently build this configuration:

$ ./test/runner other.test_freetype* -v
using verbose test runner (verbose output requested)
Running 4 tests
Using 4 parallel test processes
[1/4] test_freetype_with_pthreads (test_other.other.test_freetype_with_pthreads) ... ok
[2/4] test_freetype_wasm (test_other.other.test_freetype_wasm) ... ok
[3/4] test_freetype_wasm_legacy (test_other.other.test_freetype_wasm_legacy) ... ok
[4/4] test_freetype_emscripten (test_other.other.test_freetype_emscripten) ... ok

Added test_freetype_wasm_eh in test_other.py with a companion test_freetype_exc.cpp

The test builds a C++ file that uses both try/catch (to emit new-EH instructions) and FT_Init_FreeType() (to link FreeType) with -fwasm-exceptions -sWASM_LEGACY_EXCEPTIONS=0 -sSUPPORT_LONGJMP=wasm.

It verifies via -v build output that libfreetype-wasmsjlj.a (new-EH variant) is selected, not libfreetype-legacysjlj.a. Without the fix the assertion fails because the port falls back to the legacy variant.

Note: The test runner uses Node.js 22 with --experimental-wasm-exnref. In our testing, this configuration runs the mixed-EH binary without error, so the runtime instantiation failure cannot be reproduced here. The test therefore verifies the correct port variant by checking the library name in -v build output

Comment thread tools/ports/freetype.py Outdated
leehyeonseop and others added 3 commits April 21, 2026 04:22
-sSUPPORT_LONGJMP=wasm already implies the necessary backend flags
(-exception-model=wasm, -wasm-use-legacy-eh=0) so -fwasm-exceptions
is not needed for this pure-C library.
Comment thread test/test_other.py
proc = self.run_process([
EMCC, '-v',
test_file('test_freetype_exc.cpp'),
'-fwasm-exceptions',
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Remove this here and below?

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