Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
31 changes: 31 additions & 0 deletions test/test_freetype_exc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Minimal test that links FreeType and exercises C++ exception handling.
* When the freetype port is built with legacy EH but the application uses
* standardized Wasm EH (-sWASM_LEGACY_EXCEPTIONS=0), the resulting .wasm
* contains a mix of legacy and new EH instructions and fails at
* instantiation time.
*/
#include <cstdio>
#include <stdexcept>
#include <ft2build.h>
#include FT_FREETYPE_H

int main() {
// Exercise C++ exception handling so that new-EH instructions are emitted.
try {
throw std::runtime_error("test");
} catch (const std::exception& e) {
printf("caught: %s\n", e.what());
}

// Also call into FreeType so it is actually linked.
FT_Library library;
FT_Error error = FT_Init_FreeType(&library);
if (error) {
printf("FT_Init_FreeType failed: %d\n", error);
return 1;
}
printf("FreeType initialized successfully\n");
FT_Done_FreeType(library);
return 0;
}
33 changes: 33 additions & 0 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -2632,6 +2632,39 @@ def test_freetype_with_pthreads(self):
# Verify that freetype supports compilation requiring pthreads
self.emcc('test_freetype.c', ['-pthread', '-sUSE_FREETYPE', '-o', 'a.out.js'])

@requires_network
def test_freetype_wasm_eh(self):
# Verify that the freetype port selects the correct new-EH variant
# (libfreetype-wasmsjlj.a) when using standardized Wasm EH combined with
# SUPPORT_LONGJMP=wasm. Without the new-EH variant the port falls back to
# libfreetype-legacysjlj.a which is built with legacy EH instructions,
# causing "module uses a mix of legacy and new exception handling
# instructions" at instantiation time in browsers.
# Node.js with --experimental-wasm-exnref tolerates mixed EH, so we
# verify correctness by checking the cached library name and also
# confirming the program runs.
self.require_wasm_eh()

# Build with -v and capture stderr to verify the correct variant is used.
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?

'-sUSE_FREETYPE',
'-sSUPPORT_LONGJMP=wasm',
'-sWASM_LEGACY_EXCEPTIONS=0',
'-o', 'test_out.js',
], stderr=PIPE)
self.assertContained('libfreetype-wasmsjlj', proc.stderr)
self.assertNotContained('libfreetype-legacysjlj', proc.stderr)

# Also verify the program actually runs.
self.do_runf('test_freetype_exc.cpp', 'caught: test\nFreeType initialized successfully\n', cflags=[
'-fwasm-exceptions',
'-sUSE_FREETYPE',
'-sSUPPORT_LONGJMP=wasm',
])

@requires_network
def test_icu(self):
self.set_setting('USE_ICU')
Expand Down
13 changes: 11 additions & 2 deletions tools/ports/freetype.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
PKG_VERSION = '26.2.20'
HASH = 'ce413487c24e689631d705f53b64725256f89fffe9aade7cf07bbd785a9cd49eb6b8d2297a55554f3fee0a50b17e8af78f505cdab565768afab833794f968c2f'

variants = {'freetype-legacysjlj': {'SUPPORT_LONGJMP': 'wasm', 'WASM_LEGACY_EXCEPTIONS': 1}}
variants = {
'freetype-legacysjlj': {'SUPPORT_LONGJMP': 'wasm', 'WASM_LEGACY_EXCEPTIONS': 1},
'freetype-wasmsjlj': {'SUPPORT_LONGJMP': 'wasm', 'WASM_LEGACY_EXCEPTIONS': 0},
}
deps = ['zlib']


Expand All @@ -20,7 +23,10 @@ def needed(settings):

def get_lib_name(settings):
if settings.SUPPORT_LONGJMP == 'wasm':
return 'libfreetype-legacysjlj.a'
if settings.WASM_LEGACY_EXCEPTIONS:
return 'libfreetype-legacysjlj.a'
else:
return 'libfreetype-wasmsjlj.a'
else:
return 'libfreetype.a'

Expand Down Expand Up @@ -97,6 +103,9 @@ def create(final):

if settings.SUPPORT_LONGJMP == 'wasm':
flags.append('-sSUPPORT_LONGJMP=wasm')
if not settings.WASM_LEGACY_EXCEPTIONS:
flags.append('-fwasm-exceptions')
Comment thread
leehyeonseop marked this conversation as resolved.
Outdated
flags.append('-sWASM_LEGACY_EXCEPTIONS=0')

ports.make_pkg_config('freetype2', PKG_VERSION, '-sUSE_FREETYPE')
ports.build_port(source_path, final, 'freetype', flags=flags, srcs=srcs)
Expand Down