Skip to content

Commit 058fa51

Browse files
authored
Fix libpng and libfreetype port with wasm exceptions are enabled (#19004)
Sadly, even though libpng can be compiled with setjmp/longjmp support some libraries such as openjpeg assume that setjmp support is included. Fixes: #19001
1 parent 1db2a1e commit 058fa51

File tree

5 files changed

+54
-30
lines changed

5 files changed

+54
-30
lines changed

test/common.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,30 @@ def metafunc(self, with_bigint):
294294
return metafunc
295295

296296

297+
# This works just like `with_both_eh_sjlj` above but doesn't enable exceptions.
298+
# Use this for tests that use setjmp/longjmp but not exceptions handling.
299+
def with_both_sjlj(f):
300+
assert callable(f)
301+
302+
def metafunc(self, is_native):
303+
if is_native:
304+
if not self.is_wasm():
305+
self.skipTest('wasm2js does not support wasm SjLj')
306+
self.require_wasm_eh()
307+
# FIXME Temporarily disabled. Enable this later when the bug is fixed.
308+
if '-fsanitize=address' in self.emcc_args:
309+
self.skipTest('Wasm EH does not work with asan yet')
310+
self.set_setting('SUPPORT_LONGJMP', 'wasm')
311+
f(self)
312+
else:
313+
self.set_setting('SUPPORT_LONGJMP', 'emscripten')
314+
f(self)
315+
316+
metafunc._parameterize = {'': (False,),
317+
'wasm_sjlj': (True,)}
318+
return metafunc
319+
320+
297321
def ensure_dir(dirname):
298322
dirname = Path(dirname)
299323
dirname.mkdir(parents=True, exist_ok=True)

test/test_core.py

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from common import skip_if, needs_dylink, no_windows, no_mac, is_slow_test, parameterized
2929
from common import env_modify, with_env_modify, disabled, node_pthreads, also_with_wasm_bigint
3030
from common import read_file, read_binary, requires_v8, requires_node, compiler_for, crossplatform
31+
from common import with_both_sjlj
3132
from common import NON_ZERO, WEBIDL_BINDER, EMBUILDER, PYTHON
3233
import clang_native
3334

@@ -124,31 +125,6 @@ def metafunc(self, is_native):
124125
return metafunc
125126

126127

127-
# This works just like `with_both_eh_sjlj` above but doesn't enable exceptions.
128-
# Use this for tests that use setjmp/longjmp but not exceptions handling.
129-
def with_both_sjlj(f):
130-
assert callable(f)
131-
132-
def metafunc(self, is_native):
133-
if is_native:
134-
# Wasm SjLj is currently supported only in wasm backend and V8
135-
if not self.is_wasm():
136-
self.skipTest('wasm2js does not support wasm SjLj')
137-
self.require_wasm_eh()
138-
# FIXME Temporarily disabled. Enable this later when the bug is fixed.
139-
if '-fsanitize=address' in self.emcc_args:
140-
self.skipTest('Wasm EH does not work with asan yet')
141-
self.set_setting('SUPPORT_LONGJMP', 'wasm')
142-
f(self)
143-
else:
144-
self.set_setting('SUPPORT_LONGJMP', 'emscripten')
145-
f(self)
146-
147-
metafunc._parameterize = {'': (False,),
148-
'wasm': (True,)}
149-
return metafunc
150-
151-
152128
def no_wasm2js(note=''):
153129
assert not callable(note)
154130

test/test_other.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
from common import env_modify, no_mac, no_windows, requires_native_clang, with_env_modify
3434
from common import create_file, parameterized, NON_ZERO, node_pthreads, TEST_ROOT, test_file
3535
from common import compiler_for, EMBUILDER, requires_v8, requires_node, requires_wasm64
36-
from common import requires_wasm_eh, crossplatform
36+
from common import requires_wasm_eh, crossplatform, with_both_sjlj
3737
from common import also_with_minimal_runtime, also_with_wasm_bigint, EMTEST_BUILD_VERBOSE, PYTHON
3838
from tools import shared, building, utils, deps_info, response_file, cache
3939
from tools.utils import read_file, write_file, delete_file, read_binary
@@ -2205,6 +2205,7 @@ def test_bzip2(self):
22052205
self.do_runf(test_file('bzip2_test.c'), 'usage: unzcrash filename',
22062206
emcc_args=['-sUSE_BZIP2', '-Wno-pointer-sign'])
22072207

2208+
@with_both_sjlj
22082209
def test_freetype(self):
22092210
# copy the Liberation Sans Bold truetype file located in the
22102211
# <emscripten_root>/test/freetype to the compilation folder

tools/ports/freetype.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,20 @@
88
TAG = 'version_1'
99
HASH = '0d0b1280ba0501ad0a23cf1daa1f86821c722218b59432734d3087a89acd22aabd5c3e5e1269700dcd41e87073046e906060f167c032eb91a3ac8c5808a02783'
1010

11+
variants = {'freetype-wasm-sjlj': {'SUPPORT_LONGJMP': 'wasm'}}
12+
1113

1214
def needed(settings):
1315
return settings.USE_FREETYPE
1416

1517

18+
def get_lib_name(settings):
19+
if settings.SUPPORT_LONGJMP == 'wasm':
20+
return 'libfreetype-wasm-sjlj.a'
21+
else:
22+
return 'libfreetype.a'
23+
24+
1625
def get(ports, settings, shared):
1726
ports.fetch_project('freetype', f'https://github.com/emscripten-ports/FreeType/archive/{TAG}.zip', sha512hash=HASH)
1827

@@ -90,13 +99,16 @@ def create(final):
9099
'-pthread'
91100
]
92101

102+
if settings.SUPPORT_LONGJMP == 'wasm':
103+
flags.append('-sSUPPORT_LONGJMP=wasm')
104+
93105
ports.build_port(source_path, final, 'freetype', flags=flags, srcs=srcs)
94106

95-
return [shared.cache.get_lib('libfreetype.a', create, what='port')]
107+
return [shared.cache.get_lib(get_lib_name(settings), create, what='port')]
96108

97109

98110
def clear(ports, settings, shared):
99-
shared.cache.erase_lib('libfreetype.a')
111+
shared.cache.erase_lib(get_lib_name(settings))
100112

101113

102114
def process_args(ports):

tools/ports/libpng.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,24 @@
1010
HASH = '2ce2b855af307ca92a6e053f521f5d262c36eb836b4810cb53c809aa3ea2dcc08f834aee0ffd66137768a54397e28e92804534a74abb6fc9f6f3127f14c9c338'
1111

1212
deps = ['zlib']
13-
variants = {'libpng-mt': {'PTHREADS': 1}}
13+
variants = {
14+
'libpng-mt': {'PTHREADS': 1},
15+
'libpng-wasm-sjlj': {'SUPPORT_LONGJMP': 'wasm'},
16+
'libpng-mt-wasm-sjlj': {'PTHREADS': 1, 'SUPPORT_LONGJMP': 'wasm'},
17+
}
1418

1519

1620
def needed(settings):
1721
return settings.USE_LIBPNG
1822

1923

2024
def get_lib_name(settings):
21-
return 'libpng' + ('-mt' if settings.PTHREADS else '') + '.a'
25+
suffix = ''
26+
if settings.PTHREADS:
27+
suffix += '-mt'
28+
if settings.SUPPORT_LONGJMP == 'wasm':
29+
suffix += '-wasm-sjlj'
30+
return f'libpng{suffix}.a'
2231

2332

2433
def get(ports, settings, shared):
@@ -35,6 +44,8 @@ def create(final):
3544
flags = ['-sUSE_ZLIB']
3645
if settings.PTHREADS:
3746
flags += ['-pthread']
47+
if settings.SUPPORT_LONGJMP == 'wasm':
48+
flags.append('-sSUPPORT_LONGJMP=wasm')
3849

3950
ports.build_port(source_path, final, 'libpng', flags=flags, exclude_files=['pngtest'], exclude_dirs=['scripts', 'contrib'])
4051

0 commit comments

Comments
 (0)