Skip to content

Expose exceptions proposal configuration on C API#11861

Merged
alexcrichton merged 4 commits intobytecodealliance:mainfrom
MU-Software:main
Oct 16, 2025
Merged

Expose exceptions proposal configuration on C API#11861
alexcrichton merged 4 commits intobytecodealliance:mainfrom
MU-Software:main

Conversation

@MU-Software
Copy link
Contributor

@MU-Software MU-Software commented Oct 15, 2025

This PR makes wasmtime exceptions configuration available through the C API.
The goal is to let downstream bindings like wasmtime-py configure exceptions proposal directly. (Yeah, That's what I'm trying to do 😋)

This is similar in spirit to #7811, which also added configuration.

Verified that the new API compiles and links correctly via the C API build (cargo build --release --manifest-path crates/c-api/Cargo.toml).

@MU-Software MU-Software requested a review from a team as a code owner October 15, 2025 11:51
@MU-Software MU-Software requested review from alexcrichton and removed request for a team October 15, 2025 11:51
@MU-Software MU-Software changed the title Expose exception proposal configuration on C API Expose exceptions proposal configuration on C API Oct 15, 2025
@github-actions github-actions bot added the wasmtime:c-api Issues pertaining to the C API. label Oct 15, 2025
@alexcrichton
Copy link
Member

Thanks for the PR! This is actually missing the Rust-side implementation, though, for example a copy of this function. While the C API builds the error would come about when an external embedding (e.g. wasmtime-py) would lookup the symbol and that would fail. If you'd like you could add a test too which wuold expose the linking failure, but this is a pretty minor function so it's also ok to skip the test.

@MU-Software
Copy link
Contributor Author

MU-Software commented Oct 16, 2025

Oh, thanks for the quick reply—and sorry about the omissions. 🙏
Please feel free to review; I’m very new here. 😄

I added the missing setter functions in 33efd6b and a small use case for a smoke test in b533a96. I also found the doc and ran a test—it seems to work well!

Test result
CTEST_OUTPUT_ON_FAILURE=1 cmake --build examples/build --config Debug --target test
Running tests...
Test project /Users/musoftware/workspace_musoftware/wasmtime/examples/build
      Start  1: anyref-c
 1/96 Test  #1: anyref-c .........................   Passed    0.82 sec
      Start  2: anyref-cpp-c
 2/96 Test  #2: anyref-cpp-c .....................   Passed    0.86 sec
      Start  3: async-c
 3/96 Test  #3: async-c ..........................   Passed    1.84 sec
      Start  4: externref-c
 4/96 Test  #4: externref-c ......................   Passed    1.02 sec
      Start  5: externref-cpp-c
 5/96 Test  #5: externref-cpp-c ..................   Passed    0.82 sec
      Start  6: fib-debug-c
 6/96 Test  #6: fib-debug-c ......................   Passed    0.84 sec
      Start  7: fuel-c
 7/96 Test  #7: fuel-c ...........................   Passed    0.83 sec
      Start  8: fuel-cpp-c
 8/96 Test  #8: fuel-cpp-c .......................   Passed    0.83 sec
      Start  9: gcd-c
 9/96 Test  #9: gcd-c ............................   Passed    0.84 sec
      Start 10: gcd-cpp-c
10/96 Test #10: gcd-cpp-c ........................   Passed    0.80 sec
      Start 11: hello-c
11/96 Test #11: hello-c ..........................   Passed    0.83 sec
      Start 12: hello-cpp-c
12/96 Test #12: hello-cpp-c ......................   Passed    0.86 sec
      Start 13: interrupt-c
13/96 Test #13: interrupt-c ......................   Passed    1.83 sec
      Start 14: interrupt-cpp-c
14/96 Test #14: interrupt-cpp-c ..................   Passed    1.84 sec
      Start 15: linking-c
15/96 Test #15: linking-c ........................   Passed    1.07 sec
      Start 16: linking-cpp-c
16/96 Test #16: linking-cpp-c ....................   Passed    0.82 sec
      Start 17: memory-c
17/96 Test #17: memory-c .........................   Passed    0.84 sec
      Start 18: memory-cpp-c
18/96 Test #18: memory-cpp-c .....................   Passed    0.87 sec
      Start 19: multi-c
19/96 Test #19: multi-c ..........................   Passed    0.82 sec
      Start 20: multi-cpp-c
20/96 Test #20: multi-cpp-c ......................   Passed    0.83 sec
      Start 21: multimemory-c
21/96 Test #21: multimemory-c ....................   Passed    0.83 sec
      Start 22: multimemory-cpp-c
22/96 Test #22: multimemory-cpp-c ................   Passed    0.84 sec
      Start 23: serialize-c
23/96 Test #23: serialize-c ......................   Passed    0.82 sec
      Start 24: serialize-cpp-c
24/96 Test #24: serialize-cpp-c ..................   Passed    0.86 sec
      Start 25: threads-c
25/96 Test #25: threads-c ........................   Passed    1.15 sec
      Start 26: threads-cpp-c
26/96 Test #26: threads-cpp-c ....................   Passed    1.17 sec
      Start 27: wasip1-c
27/96 Test #27: wasip1-c .........................   Passed    0.94 sec
      Start 28: wasip1-cpp-c
28/96 Test #28: wasip1-cpp-c .....................   Passed    1.13 sec
      Start 29: Engine.Smoke
29/96 Test #29: Engine.Smoke .....................   Passed    0.03 sec
      Start 30: Engine.Simple
30/96 Test #30: Engine.Simple ....................   Passed    0.01 sec
      Start 31: wat2wasm.Smoke
31/96 Test #31: wat2wasm.Smoke ...................   Passed    0.01 sec
      Start 32: wat2wasm.Simple
32/96 Test #32: wat2wasm.Simple ..................   Passed    0.01 sec
      Start 33: Module.Smoke
33/96 Test #33: Module.Smoke .....................   Passed    0.02 sec
      Start 34: Module.Serialize
34/96 Test #34: Module.Serialize .................   Passed    0.01 sec
      Start 35: Module.Simple
35/96 Test #35: Module.Simple ....................   Passed    0.01 sec
      Start 36: ExternRef.Smoke
36/96 Test #36: ExternRef.Smoke ..................   Passed    0.01 sec
      Start 37: Caller.Smoke
37/96 Test #37: Caller.Smoke .....................   Passed    0.03 sec
      Start 38: Func.Smoke
38/96 Test #38: Func.Smoke .......................   Passed    0.01 sec
      Start 39: Data.Smoke
39/96 Test #39: Data.Smoke .......................   Passed    0.01 sec
      Start 40: ValType.Smoke
40/96 Test #40: ValType.Smoke ....................   Passed    0.01 sec
      Start 41: ValType.Simple
41/96 Test #41: ValType.Simple ...................   Passed    0.01 sec
      Start 42: MemoryType.Smoke
42/96 Test #42: MemoryType.Smoke .................   Passed    0.01 sec
      Start 43: MemoryType.SixtyFour
43/96 Test #43: MemoryType.SixtyFour .............   Passed    0.01 sec
      Start 44: MemoryType.Simple
44/96 Test #44: MemoryType.Simple ................   Passed    0.01 sec
      Start 45: MemoryType.WithMax
45/96 Test #45: MemoryType.WithMax ...............   Passed    0.01 sec
      Start 46: MemoryType.Mem64
46/96 Test #46: MemoryType.Mem64 .................   Passed    0.01 sec
      Start 47: MemoryType.Builder
47/96 Test #47: MemoryType.Builder ...............   Passed    0.01 sec
      Start 48: TableType.Smoke
48/96 Test #48: TableType.Smoke ..................   Passed    0.01 sec
      Start 49: TableType.Simple
49/96 Test #49: TableType.Simple .................   Passed    0.01 sec
      Start 50: GlobalType.Smoke
50/96 Test #50: GlobalType.Smoke .................   Passed    0.01 sec
      Start 51: GlobalType.Simple
51/96 Test #51: GlobalType.Simple ................   Passed    0.01 sec
      Start 52: ModuleType.Smoke
52/96 Test #52: ModuleType.Smoke .................   Passed    0.01 sec
      Start 53: ValKind.String
53/96 Test #53: ValKind.String ...................   Passed    0.01 sec
      Start 54: FuncType.Smoke
54/96 Test #54: FuncType.Smoke ...................   Passed    0.01 sec
      Start 55: ImportType.Smoke
55/96 Test #55: ImportType.Smoke .................   Passed    0.01 sec
      Start 56: ExportType.Smoke
56/96 Test #56: ExportType.Smoke .................   Passed    0.01 sec
      Start 57: ExternType.Smoke
57/96 Test #57: ExternType.Smoke .................   Passed    0.01 sec
      Start 58: TypedFunc.Smoke
58/96 Test #58: TypedFunc.Smoke ..................   Passed    0.01 sec
      Start 59: TypedFunc.Call
59/96 Test #59: TypedFunc.Call ...................   Passed    0.01 sec
      Start 60: TypedFunc.WrapAndTypes
60/96 Test #60: TypedFunc.WrapAndTypes ...........   Passed    0.01 sec
      Start 61: TypedFunc.WrapRuntime
61/96 Test #61: TypedFunc.WrapRuntime ............   Passed    0.01 sec
      Start 62: component.instantiate
62/96 Test #62: component.instantiate ............   Passed    0.01 sec
      Start 63: component.define_module
63/96 Test #63: component.define_module ..........   Passed    0.01 sec
      Start 64: component.lookup_func
64/96 Test #64: component.lookup_func ............   Passed    0.01 sec
      Start 65: component.call_func
65/96 Test #65: component.call_func ..............   Passed    0.01 sec
      Start 66: component.value_record
66/96 Test #66: component.value_record ...........   Passed    0.02 sec
      Start 67: component.value_string
67/96 Test #67: component.value_string ...........   Passed    0.01 sec
      Start 68: component.value_list
68/96 Test #68: component.value_list .............   Passed    0.01 sec
      Start 69: component.value_tuple
69/96 Test #69: component.value_tuple ............   Passed    0.01 sec
      Start 70: component.value_variant
70/96 Test #70: component.value_variant ..........   Passed    0.01 sec
      Start 71: component.value_enum
71/96 Test #71: component.value_enum .............   Passed    0.01 sec
      Start 72: component.value_option
72/96 Test #72: component.value_option ...........   Passed    0.01 sec
      Start 73: component.value_result
73/96 Test #73: component.value_result ...........   Passed    0.01 sec
      Start 74: component.value_flags
74/96 Test #74: component.value_flags ............   Passed    0.01 sec
      Start 75: component.value_list_inner
75/96 Test #75: component.value_list_inner .......   Passed    0.01 sec
      Start 76: Result.Simple
76/96 Test #76: Result.Simple ....................   Passed    0.01 sec
      Start 77: Error.Simple
77/96 Test #77: Error.Simple .....................   Passed    0.01 sec
      Start 78: PoolAllocationConfig.Smoke
78/96 Test #78: PoolAllocationConfig.Smoke .......   Passed    0.01 sec
      Start 79: Config.Smoke
79/96 Test #79: Config.Smoke .....................   Passed    0.01 sec
      Start 80: Config.MemoryCreator
80/96 Test #80: Config.MemoryCreator .............   Passed    0.01 sec
      Start 81: Trap.Smoke
81/96 Test #81: Trap.Smoke .......................   Passed    0.01 sec
      Start 82: Trap.Codes
82/96 Test #82: Trap.Codes .......................   Passed    0.01 sec
      Start 83: WasiConfig.Smoke
83/96 Test #83: WasiConfig.Smoke .................   Passed    0.01 sec
      Start 84: Store.Smoke
84/96 Test #84: Store.Smoke ......................   Passed    0.01 sec
      Start 85: Val.Smoke
85/96 Test #85: Val.Smoke ........................   Passed    0.01 sec
      Start 86: Val.DropsExternRef
86/96 Test #86: Val.DropsExternRef ...............   Passed    0.01 sec
      Start 87: Table.Smoke
87/96 Test #87: Table.Smoke ......................   Passed    0.01 sec
      Start 88: Global.Smoke
88/96 Test #88: Global.Smoke .....................   Passed    0.01 sec
      Start 89: Memory.Smoke
89/96 Test #89: Memory.Smoke .....................   Passed    0.01 sec
      Start 90: Instance.Smoke
90/96 Test #90: Instance.Smoke ...................   Passed    0.01 sec
      Start 91: Linker.Smoke
91/96 Test #91: Linker.Smoke .....................   Passed    0.01 sec
      Start 92: Linker.CallableMove
92/96 Test #92: Linker.CallableMove ..............   Passed    0.01 sec
      Start 93: Linker.CallableCopy
93/96 Test #93: Linker.CallableCopy ..............   Passed    0.01 sec
      Start 94: wasip2.smoke
94/96 Test #94: wasip2.smoke .....................   Passed    0.01 sec
      Start 95: Store.WorksInFileA
95/96 Test #95: Store.WorksInFileA ...............   Passed    0.02 sec
      Start 96: Store.WorksInFileB
96/96 Test #96: Store.WorksInFileB ...............   Passed    0.01 sec

100% tests passed, 0 tests failed out of 96

Total Test time (real) =  28.70 sec

And it works with wasmtime-py, too! 🎉


# uv run python
Python 3.13.1 (main, Jan 14 2025, 23:31:50) [Clang 19.1.6 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
Cmd click to launch VS Code Native REPL
>>> from wasmtime import Config, Store, Module, Instance, Engine
>>> cfg = Config()
>>> cfg.wasm_exceptions = True
>>> engine = Engine(cfg)
>>> from pathlib import Path
>>> mpy = Path.cwd() / 'micropython.wasm'
>>> micropython_store = Store(engine)
>>> micropython_module = Module.from_file(micropython_store.engine, mpy)
>>> micropython_module.exports
[<wasmtime._types.ExportType object at 0x1017f8050>, <wasmtime._types.ExportType object at 0x101633d90>, <wasmtime._types.ExportType object at 0x1016339d0>, <wasmtime._types.ExportType object at 0x101680c30>, <wasmtime._types.ExportType object at 0x101680e90>, <wasmtime._types.ExportType object at 0x1014c8dd0>, <wasmtime._types.ExportType object at 0x101613020>, <wasmtime._types.ExportType object at 0x101612f10>, <wasmtime._types.ExportType object at 0x1017e0650>, <wasmtime._types.ExportType object at 0x1017e0750>]
>>>

For the comparison, current release cannot handle that.

---------------------------------------------------------------------------
WasmtimeError                             Traceback (most recent call last)
Cell In[8], line 5
      3 micropython_path = Path.cwd() / "micropython.wasm"
      4 micropython_store = Store(engine)
----> 5 micropython_module = Module.from_file(micropython_store.engine, micropython_path)

File [/opt/homebrew/Cellar/jupyterlab/4.3.6/libexec/lib/python3.13/site-packages/wasmtime/_module.py:20](http://localhost:8888/opt/homebrew/Cellar/jupyterlab/4.3.6/libexec/lib/python3.13/site-packages/wasmtime/_module.py#line=19), in Module.from_file(cls, engine, path)
     18 with open(path, "rb") as f:
     19     contents = f.read()
---> 20 return cls(engine, contents)

File [/opt/homebrew/Cellar/jupyterlab/4.3.6/libexec/lib/python3.13/site-packages/wasmtime/_module.py:45](http://localhost:8888/opt/homebrew/Cellar/jupyterlab/4.3.6/libexec/lib/python3.13/site-packages/wasmtime/_module.py#line=44), in Module.__init__(self, engine, wasm)
     43 error = ffi.wasmtime_module_new(engine.ptr(), binary, len(wasm), byref(ptr))
     44 if error:
---> 45     raise WasmtimeError._from_ptr(error)
     46 self._set_ptr(ptr)

WasmtimeError: failed to parse WebAssembly module

Caused by:
    exceptions proposal not enabled (at offset 0xb0c)

Copy link
Member

@alexcrichton alexcrichton left a comment

Choose a reason for hiding this comment

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

No worries, and this all looks great, thanks!

@alexcrichton alexcrichton added this pull request to the merge queue Oct 16, 2025
Merged via the queue into bytecodealliance:main with commit ca4a236 Oct 16, 2025
49 checks passed
bongjunj pushed a commit to prosyslab/wasmtime that referenced this pull request Oct 20, 2025
…1861)

* c-api: expose exceptions configuration option to c api

* chore: Fix lint error

* fix: Add missing implementation of exceptions proposal config setter function on rust side

* feat: Add use cases on smoke test
cfallin added a commit to cfallin/wasmtime that referenced this pull request Nov 17, 2025
Noticed while reviewing another docs update: we still state that the
exceptions proposal is not fuzzed, and has no C API support. Neither is
true anymore, AFAIK:

- We fuzz exceptions via our usual infrastructure and we had a number of
  fuzzbugs come in when we first merged support.
- We added C API support for enabling exceptions in bytecodealliance#11861.
github-merge-queue bot pushed a commit that referenced this pull request Nov 17, 2025
* Docs: update exceptions proposal fuzzing and C-API status.

Noticed while reviewing another docs update: we still state that the
exceptions proposal is not fuzzed, and has no C API support. Neither is
true anymore, AFAIK:

- We fuzz exceptions via our usual infrastructure and we had a number of
  fuzzbugs come in when we first merged support.
- We added C API support for enabling exceptions in #11861.

* Review feedback.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wasmtime:c-api Issues pertaining to the C API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants