Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
5 changes: 3 additions & 2 deletions .github/workflows/linux-wasm-ci-build-and-test-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ jobs:
--use_jsep \
--use_webnn \
--target onnxruntime_webassembly \
${{ inputs.build_config == 'Release' && '--enable_wasm_api_exception_catching' || '' }} \
--enable_wasm_eh \
--skip_tests
working-directory: ${{ github.workspace }}

Expand All @@ -108,7 +108,7 @@ jobs:
--use_webgpu \
--use_webnn \
--target onnxruntime_webassembly \
${{ inputs.build_config == 'Release' && '--enable_wasm_api_exception_catching' || '' }} \
--enable_wasm_eh \
--skip_tests
working-directory: ${{ github.workspace }}

Expand All @@ -121,6 +121,7 @@ jobs:
--use_webgpu \
--use_webnn \
--enable_wasm_jspi \
--enable_wasm_eh \
--target onnxruntime_webassembly \
--skip_tests
working-directory: ${{ github.workspace }}
Expand Down
1 change: 1 addition & 0 deletions cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ option(onnxruntime_ENABLE_WEBASSEMBLY_THREADS "Enable this option to create WebA
option(onnxruntime_ENABLE_WEBASSEMBLY_EXCEPTION_CATCHING "Enable this option to turn on exception catching" OFF)
option(onnxruntime_ENABLE_WEBASSEMBLY_API_EXCEPTION_CATCHING "Enable this option to turn on api exception catching" OFF)
option(onnxruntime_ENABLE_WEBASSEMBLY_EXCEPTION_THROWING "Enable this option to turn on exception throwing even if the build disabled exceptions support" OFF)
option(onnxruntime_ENABLE_WEBASSEMBLY_NATIVE_EH "Enable native WebAssembly exception handling (-fwasm-exceptions) instead of legacy JavaScript-based exception support" OFF)
option(onnxruntime_WEBASSEMBLY_RUN_TESTS_IN_BROWSER "Enable this option to run tests in browser instead of Node.js" OFF)
option(onnxruntime_ENABLE_WEBASSEMBLY_DEBUG_INFO "Enable this option to turn on DWARF format debug info" OFF)
option(onnxruntime_ENABLE_WEBASSEMBLY_PROFILING "Enable this option to turn on WebAssembly profiling and preserve function names" OFF)
Expand Down
6 changes: 3 additions & 3 deletions cmake/adjust_global_compile_flags.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
endif()

# Enable WebAssembly exception catching.
if (onnxruntime_ENABLE_WEBASSEMBLY_JSPI)
string(APPEND CMAKE_C_FLAGS " -fwasm-exceptions -s WASM_LEGACY_EXCEPTIONS=0")
string(APPEND CMAKE_CXX_FLAGS " -fwasm-exceptions -s WASM_LEGACY_EXCEPTIONS=0")
if (onnxruntime_ENABLE_WEBASSEMBLY_NATIVE_EH)
string(APPEND CMAKE_C_FLAGS " -fwasm-exceptions")
string(APPEND CMAKE_CXX_FLAGS " -fwasm-exceptions")
elseif (onnxruntime_ENABLE_WEBASSEMBLY_EXCEPTION_CATCHING)
string(APPEND CMAKE_C_FLAGS " -s DISABLE_EXCEPTION_CATCHING=0")
string(APPEND CMAKE_CXX_FLAGS " -s DISABLE_EXCEPTION_CATCHING=0")
Expand Down
2 changes: 1 addition & 1 deletion cmake/onnxruntime_webassembly.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ else()
endif()
endif()

if (NOT onnxruntime_ENABLE_WEBASSEMBLY_JSPI)
if (NOT onnxruntime_ENABLE_WEBASSEMBLY_NATIVE_EH)
# Set link flag to enable exceptions support, this will override default disabling exception throwing behavior when disable exceptions.
target_link_options(onnxruntime_webassembly PRIVATE
"SHELL:-s DISABLE_EXCEPTION_THROWING=0"
Expand Down
4 changes: 2 additions & 2 deletions js/build_jsep.bat
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ if ["%~1"]==["d"] (
)
if ["%~1"]==["r"] (
set CONFIG=Release
set CONFIG_EXTRA_FLAG=--enable_wasm_api_exception_catching --disable_rtti --enable_wasm_profiling
set CONFIG_EXTRA_FLAG=--disable_rtti --enable_wasm_profiling
goto :arg2
)
echo Invalid configuration "%~1", must be "d"(Debug) or "r"(Release)
Expand Down Expand Up @@ -64,7 +64,7 @@ popd

set PATH=C:\Program Files\Git\usr\bin;%PATH%

call %ROOT%build.bat --config %CONFIG% %CONFIG_EXTRA_FLAG% --skip_submodule_sync --build_wasm --skip_tests^
call %ROOT%build.bat --config %CONFIG% %CONFIG_EXTRA_FLAG% --skip_submodule_sync --build_wasm --skip_tests --enable_wasm_eh^
--enable_wasm_simd --enable_wasm_threads --use_jsep --use_webnn --target onnxruntime_webassembly --build_dir %BUILD_DIR%

IF NOT "%ERRORLEVEL%" == "0" (
Expand Down
3 changes: 2 additions & 1 deletion tools/ci_build/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ def generate_build_tree(
+ ("ON" if args.enable_wasm_api_exception_catching else "OFF"),
"-Donnxruntime_ENABLE_WEBASSEMBLY_EXCEPTION_THROWING="
+ ("ON" if args.enable_wasm_exception_throwing_override else "OFF"),
"-Donnxruntime_ENABLE_WEBASSEMBLY_NATIVE_EH=" + ("ON" if args.enable_wasm_eh else "OFF"),
"-Donnxruntime_WEBASSEMBLY_RUN_TESTS_IN_BROWSER=" + ("ON" if args.wasm_run_tests_in_browser else "OFF"),
"-Donnxruntime_ENABLE_WEBASSEMBLY_JSPI=" + ("ON" if args.enable_wasm_jspi else "OFF"),
"-Donnxruntime_ENABLE_WEBASSEMBLY_THREADS=" + ("ON" if args.enable_wasm_threads else "OFF"),
Expand Down Expand Up @@ -619,7 +620,7 @@ def generate_build_tree(
build_dir,
configs,
emscripten_root_path,
args.enable_wasm_jspi,
args.enable_wasm_eh,
not args.disable_rtti,
not args.disable_wasm_exception_catching,
args.minimal_build is not None,
Expand Down
28 changes: 28 additions & 0 deletions tools/ci_build/build_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,11 @@ def add_webassembly_args(parser: argparse.ArgumentParser) -> None:
action="store_true",
help="Override default behavior to allow throwing exceptions even when catching is generally disabled.",
)
parser.add_argument(
"--enable_wasm_eh",
action="store_true",
help="Use native WebAssembly exception handling (-fwasm-exceptions) instead of legacy JavaScript-based exception support.",
)
parser.add_argument("--wasm_run_tests_in_browser", action="store_true", help="Run WASM tests in a browser.")
parser.add_argument(
"--enable_wasm_profiling", action="store_true", help="Enable WASM profiling and preserve function names."
Expand Down Expand Up @@ -935,7 +940,30 @@ def convert_arg_line_to_args(self, arg_line: str) -> list[str]: # Use list[str]
if args.android_ndk_path:
args.android_ndk_path = os.path.normpath(args.android_ndk_path)

if args.enable_wasm_jspi and not args.enable_wasm_eh:
raise Exception(
"'--enable_wasm_jspi' requires '--enable_wasm_eh' to be specified. "
"Currently we only support JSPI builds with native exception handling enabled."
)

# Handle WASM exception logic
if args.enable_wasm_eh:
# Native Wasm EH is incompatible with legacy exception flags
if args.disable_wasm_exception_catching:
raise Exception(
"'--enable_wasm_eh' cannot be used with '--disable_wasm_exception_catching'. "
"Native Wasm EH replaces the legacy exception catching mechanism."
)
if args.enable_wasm_api_exception_catching:
raise Exception(
"'--enable_wasm_eh' cannot be used with '--enable_wasm_api_exception_catching'. "
"Native Wasm EH replaces the legacy API-level exception catching."
)
if args.enable_wasm_exception_throwing_override:
raise Exception(
"'--enable_wasm_eh' cannot be used with '--enable_wasm_exception_throwing_override'. "
"Native Wasm EH handles exception throwing natively."
)
if args.enable_wasm_api_exception_catching:
args.disable_wasm_exception_catching = True # Catching at API level implies disabling broader catching
if not args.disable_wasm_exception_catching or args.enable_wasm_api_exception_catching:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:
buildArch: x64
CommonBuildArgs: '--parallel --config ${{ parameters.BuildConfig }} --skip_submodule_sync --build_wasm --enable_wasm_simd --enable_wasm_threads ${{ parameters.ExtraBuildArgs }}'
${{ if eq(parameters.BuildConfig, 'Release') }}:
# Add '--enable_wasm_api_exception_catching' only for non-JSPI Release build
# Add '--enable_wasm_api_exception_catching' only for basic Release build
ExceptionHandlingBuildArgs: '--enable_wasm_api_exception_catching'
${{ else }}:
ExceptionHandlingBuildArgs: ''
Expand Down Expand Up @@ -128,7 +128,7 @@ jobs:
${{ else }}:
AdditionalKey: wasm_inferencing_jsep | ${{ parameters.BuildConfig }}
CacheDir: $(ORT_CACHE_DIR)/wasm_inferencing_jsep
Arguments: '$(CommonBuildArgs) --build_dir $(Build.BinariesDirectory)/wasm_inferencing_jsep --use_jsep --use_webnn --target onnxruntime_webassembly $(ExceptionHandlingBuildArgs) --skip_tests'
Arguments: '$(CommonBuildArgs) --build_dir $(Build.BinariesDirectory)/wasm_inferencing_jsep --use_jsep --use_webnn --target onnxruntime_webassembly --enable_wasm_eh --skip_tests'
DisplayName: 'Build (simd + threads + JSEP)'
WithCache: ${{ parameters.WithCache }}

Expand All @@ -141,7 +141,7 @@ jobs:
${{ else }}:
AdditionalKey: wasm_inferencing_webgpu | ${{ parameters.BuildConfig }}
CacheDir: $(ORT_CACHE_DIR)/wasm_inferencing_webgpu
Arguments: '$(CommonBuildArgs) --build_dir $(Build.BinariesDirectory)/wasm_inferencing_webgpu --use_webgpu --use_webnn --target onnxruntime_webassembly $(ExceptionHandlingBuildArgs) --skip_tests'
Arguments: '$(CommonBuildArgs) --build_dir $(Build.BinariesDirectory)/wasm_inferencing_webgpu --use_webgpu --use_webnn --target onnxruntime_webassembly --enable_wasm_eh --skip_tests'
DisplayName: 'Build (simd + threads + WebGPU experimental)'
WithCache: ${{ parameters.WithCache }}

Expand All @@ -154,7 +154,7 @@ jobs:
${{ else }}:
AdditionalKey: wasm_inferencing_webgpu_jspi | ${{ parameters.BuildConfig }}
CacheDir: $(ORT_CACHE_DIR)/wasm_inferencing_webgpu_jspi
Arguments: '$(CommonBuildArgs) --build_dir $(Build.BinariesDirectory)/wasm_inferencing_webgpu_jspi --use_webgpu --use_webnn --enable_wasm_jspi --target onnxruntime_webassembly --skip_tests'
Arguments: '$(CommonBuildArgs) --build_dir $(Build.BinariesDirectory)/wasm_inferencing_webgpu_jspi --use_webgpu --use_webnn --enable_wasm_jspi --enable_wasm_eh --target onnxruntime_webassembly --skip_tests'
DisplayName: 'Build (simd + threads + WebGPU experimental, JSPI)'
WithCache: ${{ parameters.WithCache }}

Expand Down
25 changes: 13 additions & 12 deletions tools/python/util/vcpkg_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ def generate_vcpkg_triplets_for_emscripten(
configs: set[str],
emscripten_root: str,
# Parameters defining the specific build configuration
enable_jspi: bool,
enable_wasm_eh: bool, # Controls native Wasm EH (-fwasm-exceptions)
enable_rtti: bool,
enable_wasm_exception_catching: bool, # Controls -sDISABLE_EXCEPTION_CATCHING=...
enable_minimal_onnx_build: bool, # Controls ONNX port setting AND C++ exceptions (-fno-exceptions)
Expand All @@ -493,21 +493,21 @@ def generate_vcpkg_triplets_for_emscripten(
- If enable_minimal_onnx_build=False, C++ exceptions are assumed enabled (-fexceptions).

This supports 4 main effective EH scenarios depending on the combination of
'enable_minimal_onnx_build', 'enable_jspi' and 'enable_wasm_exception_catching':
'enable_minimal_onnx_build', 'enable_wasm_eh' and 'enable_wasm_exception_catching':
1. No EH (-fno-exceptions, -sDISABLE_EXCEPTION_CATCHING=1):
Set enable_minimal_onnx_build=True, enable_wasm_exception_catching=False
2. Full EH (-fexceptions, -sDISABLE_EXCEPTION_CATCHING=0):
Set enable_minimal_onnx_build=False, enable_wasm_exception_catching=True
3. Throw Only EH (-fexceptions, -sDISABLE_EXCEPTION_CATCHING=1):
Set enable_minimal_onnx_build=False, enable_wasm_exception_catching=False
4. Use the new Wasm EH (-fwasm-exceptions -sWASM_LEGACY_EXCEPTIONS=0):
Set enable_minimal_onnx_build=False, enable_jspi=True
4. The new Wasm native EH (-fwasm-exceptions -sWASM_LEGACY_EXCEPTIONS=0):
Set enable_minimal_onnx_build=False, enable_wasm_eh=True

Args:
build_dir (str): The directory to save the generated triplet files.
emscripten_root (str): The root path of Emscripten.
enable_jspi (bool): Flag indicating if JSPI is enabled. If JSPI is enabled, the new
Wasm EH will be used and enable_wasm_exception_catching is ignored.
enable_wasm_eh (bool): Flag indicating if native Wasm EH should be used.
If True, uses -fwasm-exceptions -sWASM_LEGACY_EXCEPTIONS=0.
enable_rtti (bool): Flag indicating if RTTI is enabled for dependencies.
enable_wasm_exception_catching (bool): Flag indicating if the Emscripten runtime
exception catching mechanism should be enabled
Expand All @@ -525,11 +525,12 @@ def generate_vcpkg_triplets_for_emscripten(
# Derive C++ exception enablement from the minimal build flag
cpp_exceptions_enabled = not enable_minimal_onnx_build

# When JSPI is enabled, use the new Wasm EH
if enable_jspi:
# When native Wasm EH is enabled, ensure minimal build is not used
if enable_wasm_eh:
if enable_minimal_onnx_build:
# TODO: support minimal build with JSPI if needed
raise ValueError("Currently minimal build cannot be used with JSPI.")
raise ValueError(
"Using minimal build means C++ exceptions are disabled, which is incompatible with enabling native Wasm EH."
)

for target_abi in ["wasm32", "wasm64"]:
os_name = "emscripten"
Expand Down Expand Up @@ -574,8 +575,8 @@ def generate_vcpkg_triplets_for_emscripten(

# Wasm Exception Catching Runtime (-s flag, apply to Base and Linker flags)
exception_catching_flag = ""
if enable_jspi:
exception_catching_flag = "-fwasm-exceptions -sWASM_LEGACY_EXCEPTIONS=0"
if enable_wasm_eh:
exception_catching_flag = "-fwasm-exceptions"
elif enable_wasm_exception_catching:
exception_catching_flag = "-sDISABLE_EXCEPTION_CATCHING=0"
else:
Expand Down
Loading