Repository navigation
Wasm implementation - #1040
Wasm implementation#1040
Conversation
New wasm/ directory builds the Minsky object with Emscripten (jsminsky.js + jsminsky.wasm). Its methods are exposed through the RESTProcess descriptor via embind, and the model canvas is drawn through mansoura::MansouraHTMLCanvas. wasm/minsky.js mirrors the C++ method tree as a Javascript object and handles mouse, wheel and key events; wasm/test.html is a demo page; wasm/test/smoke.js runs the module under node against a mock canvas (make -C wasm test). Platform changes, all behind __EMSCRIPTEN__: - header stubs for cairo and friends in wasm/stubs - RungeKutta::rkstep and BackgroundSaver run synchronously, as there are no threads - clipboard is a no-op - drop the pango.h includes, which were not needed outside Mansoura - RenderNativeWindow: drawToContext() draws into an existing context, and records the frame size, as renderFrame() would Also: mdlReader uses char32_t rather than uint32_t, as libc++ has no char_traits<uint32_t>; nobble the libc++ vector iterator. Update mansoura ref. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Minsky reads and writes NaN and Infinity as JSON5 values. Strict JSON.parse could not read them (they were being replaced by null), and JSON.stringify turned them into null on the way in. minsky.js now uses the JSON5 library for both, taken from a JSON5 global, or require(). test.html loads the copy the GUI uses, and smoke.js checks a NaN read and an Infinity round trip. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the
|
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved critical defects skip command-state updates, leak Wasm allocations, and discard clipboard contents, making cut operations destructive.
6 open issues
Wasm cut deletes selections without preserving clipboard data · New Command dispatch skips hooks for state and history updates · New Embind handles leak during calls and result enumeration · New Releasing a drag outside the canvas leaves it active · New Tab navigation is blocked when the canvas does not handle the key · New Restarting before a queued frame runs creates duplicate loops · New
What changed in this PR
Adds a WebAssembly build of Minsky, exposing the existing C++ model API to JavaScript and rendering models on an HTML canvas.
Changes:
- Adds Emscripten build rules, JavaScript bindings, and browser interaction support.
- Adapts native dependencies and threaded operations for Wasm.
- Adds a browser demo and smoke tests for simulation, rendering, and API access.
| File | Description |
|---|---|
| wasm/test/smoke.js | Tests API access, simulation, rendering, and serialization. |
| wasm/test/mockCanvas.js | Provides a recording canvas mock. |
| wasm/test.html | Adds an interactive browser demo. |
| wasm/stubs/windowInformationStub.cc | Stubs native window operations. |
| wasm/stubs/pythonBuffer.h | Removes Python binding dependencies from Wasm. |
| wasm/stubs/pango/pangocairo.h | Provides a Pango compatibility header. |
| wasm/stubs/mansouraCairo.h | Exposes drawing interfaces without Cairo. |
| wasm/stubs/cairoStub.cc | Supplies Cairo stubs and unsupported-operation errors. |
| wasm/stubs/cairo/cairo.h | Declares minimal Cairo compatibility types and functions. |
| wasm/stubs/cairo.h | Supports the alternate Cairo include path. |
| wasm/minsky.js | Wraps the model API and handles canvas interaction. |
| wasm/Makefile | Builds the Wasm module and runs smoke tests. |
| wasm/jsminsky.cc | Binds the C++ API and HTML canvas renderer. |
| wasm/.gitignore | Excludes generated Wasm build artifacts. |
| RESTService/nobble.h | Supports Emscripten iterator types in descriptors. |
| model/renderNativeWindow.h | Declares external-context rendering support. |
| model/renderNativeWindow.cc | Implements drawing into externally managed contexts. |
| model/operationRS2.cc | Removes an unnecessary Pango include. |
| model/operationRS1.cc | Removes an unnecessary Pango include. |
| model/operation.cc | Removes an unnecessary Pango include. |
| model/minsky.h | Excludes Pango headers from Wasm builds. |
| model/minsky.cc | Uses backend-independent font settings. |
| model/dataOp.cc | Removes an unnecessary Pango include. |
| model/CSVDialog.cc | Removes an unnecessary Pango include. |
| model/cairoItems.h | Makes rendering context pointers const-correct. |
| engine/saver.cc | Runs saving synchronously under Emscripten. |
| engine/rungeKutta.cc | Runs integration synchronously under Emscripten. |
| engine/mdlReader.cc | Uses standard UTF-32 character and string types. |
| engine/godleyExport.cc | Removes an unnecessary Pango include. |
| engine/clipboard.cc | Adds Wasm branches without native clipboard access. |
Review effort: Balanced
| return jsGuard([&]{ | ||
| json_pack_t jin; | ||
| read(args,jin); | ||
| return CppWrapper(wrappedObject->process("."+method, jin)); |
There was a problem hiding this comment.
Implemented in commit a6d9fff: Wasm wrappers now call commandHook after successful dispatch using parsed arguments and a fully qualified path preserved by returned wrappers. The Wasm smoke test could not run because em++ is unavailable.
| const resultObj=impl.call(fullMethod,stringify(args)); | ||
| const children=resultObj.list(); |
There was a problem hiding this comment.
Fixed in 9152728: Embind vectors and scalar results are released, and returned object wrappers now expose an idempotent dispose() method.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Added frame variable to manage animation frame cancellation. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: highperformancecoder <3075825+highperformancecoder@users.noreply.github.com>
Co-authored-by: highperformancecoder <3075825+highperformancecoder@users.noreply.github.com>


This change is