feat: STEP write under wasm (pyodide 0.29.4 / native wasm-EH)#28
Closed
Krande wants to merge 1 commit into
Closed
Conversation
backend.write_step (STEPCAFControl_Writer via OCCT XCAF) fatally aborted
the pyodide module with `RuntimeError: unreachable`. Two root causes:
1. step_writer.cpp / helpers.cpp were never compiled into the wasm side
module — the BUILD_WASM source list still carried the stale "OCCT not
available in wasm" set. write_shapes_to_step was therefore emitted as
an unresolved `env` import whose function-table slot is a trap stub,
so the first call trapped. GLB / STEP-read / make_box worked only
because they are self-contained in cad_py_wrap.cpp.
2. The OCAF document used "XmlOcaf", whose driver isn't registered under
OCCT_NO_PLUGINS (TKXml* isn't even linked for wasm). Switched to
BinXCAFDrivers::DefineFormat + a "BinXCAF" document (TKBinXCAF is
linked). write_shapes_to_step now also translates Standard_Failure
into a std::runtime_error so nanobind surfaces a Python exception
instead of std::terminate.
Requires the wasm toolchain to move to pyodide 0.29.4 / emscripten 4.0.9
/ Python 3.13 with native WebAssembly exception handling (the old
-fexceptions JS-trampoline model trapped in STEPCAFControl_Writer):
- OCCT + adacpp + nanobind all compile with -fwasm-exceptions
(+ -sSUPPORT_LONGJMP=wasm); OCC_CONVERT_SIGNALS dropped on wasm
(setjmp inside a catch is invalid under wasm-EH → "br_table: label
arity inconsistent" CompileError).
- wheel tag cp313 / pyodide_2025_0_wasm32; Python_SOABI cpython-313.
- xbuildenv path resolved dynamically via `pyodide config get` instead
of a machine-specific content hash (CI-portable).
- native test env + linux preset bumped to python 3.13 to match.
Verified: SAT -> {glb,obj,stl,xml,step} and FEM bake all succeed under
pyodide (node-pyodide harness); native suite 62 passed including
test_cad_write_step / test_basic_write_step.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
👋 Hi there! I have checked your PR and found the following: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
backend.write_step(STEPCAFControl_Writer via OCCT XCAF) fatally aborted the pyodide module withRuntimeError: unreachable/ bareAborted(). This fixes it, and migrates the wasm toolchain to pyodide 0.29.4 / emscripten 4.0.9 / Python 3.13 with native WebAssembly exception handling (required for the fix).Root cause (two parts)
step_writer.cpp/helpers.cppwere never compiled into the wasm side module. TheBUILD_WASMbranch ofCMakeLists.txtstill carried the stale "OCCT not available in wasm" source list (Color.cpp+Models.cpponly). Sowrite_shapes_to_stepwas emitted as an unresolvedenvimport whose function-table slot is a trap stub — the first call trapped withunreachable. GLB / STEP-read / make_box worked only because they are self-contained incad_py_wrap.cpp."XmlOcaf", whose driver isn't registered underOCCT_NO_PLUGINS(TKXml*isn't even linked for wasm). Switched toBinXCAFDrivers::DefineFormat+ a"BinXCAF"document (TKBinXCAFis linked).write_shapes_to_stepnow also translatesStandard_Failureinto astd::runtime_errorso nanobind surfaces a Python exception instead ofstd::terminate.Toolchain migration (pyodide 0.29.4 / wasm-EH)
The old
-fexceptionsJS-trampoline EH model fatally trapped inSTEPCAFControl_Writer; the fix needs native wasm exception handling:-fwasm-exceptions(+-sSUPPORT_LONGJMP=wasm).OCC_CONVERT_SIGNALSdropped on wasm —setjmpinside acatchis invalid under wasm-EH and made emscripten emit invalid wasm (br_table: label arity inconsistentCompileError).cp313/pyodide_2025_0_wasm32;Python_SOABI=cpython-313-wasm32-emscripten.pyodide config get python_include_dirinstead of a machine-specific content-hash path (CI-portable).testenv + linux preset bumped to Python 3.13 to matchfeature.common.Verification
SAT → {glb, obj, stl, xml, step}all ✅ (step = 6422 bytes) and FEM bake (manifest + mesh + edges + elements + 3 result fields) ✅.test_cad_write_step/test_basic_write_step(theBinXCAFpath) — works outside wasm too.CI note
This PR touches
cmake/wasm_occt.cmake/pixi.toml/CMakePresets.json, so merging triggers publish-occt-wasm-base to rebuild the OCCT-wasm base image with the new EH model (em4.0.9,-fwasm-exceptions, noOCC_CONVERT_SIGNALS).ci-wasm-tests/publish-wasm-baseconsume the base via:latest; if they run before the rebuilt base finishes they may pick up the stale (em3.1.58) base and need a re-run once the base publishes. The fallback (build OCCT from source) still produces a correct result.🤖 Generated with Claude Code