按规划继续工作

结论:解释器 WASM、SDK 统一入口、浏览器解释器 smoke 与兼容性文档已闭环,native 和 host/WASM/browser 验证全部通过。
This commit is contained in:
2026-06-08 07:24:06 +08:00
parent c28b629ff6
commit 706fd1e775
20 changed files with 629 additions and 122 deletions

View File

@@ -36,6 +36,12 @@ The current browser smoke validation command is:
wasm-port/tests/browser/verify_ini_panel_browser.sh
```
The current browser interpreter smoke validation command is:
```bash
wasm-port/tests/browser/verify_interp_browser.sh
```
The current aggregate host/WASM/browser smoke command is:
```bash
@@ -53,7 +59,8 @@ The native validation script runs these checks in order:
Confirms every manifest file is present in `vendor/linuxcnc/`, no extra
vendored file exists, and every vendored file is byte-identical to upstream.
3. `tools/verify_no_standalone_cnc_semantics.sh`
Confirms standalone code has not reintroduced `Interp::convert_g()`.
Confirms standalone code has not introduced project-owned `Interp::...`
member definitions outside the documented Python/remap runtime-edge stubs.
4. `tools/verify_native_linuxcnc_fixture_baseline.sh`
Runs a side-by-side fixture baseline through upstream
`../linuxcnc/bin/rs274` and compares normalized canonical events for
@@ -67,17 +74,18 @@ The native validation script runs these checks in order:
The WASM INI smoke script builds `runtime/ui/ini-panel/linuxcnc_ini.js` and
`linuxcnc_ini.wasm` from vendored LinuxCNC `inifile.cc`, then loads that
module through `runtime/sdk/src/linuxcnc-ini.js` in Node and verifies INI
module through `runtime/sdk/src/index.js` in Node and verifies INI
queries against a file written to the Emscripten filesystem.
The WASM interpreter-core smoke script builds
`build/wasm/core/linuxcnc_interp.js` and `linuxcnc_interp.wasm` from the same
vendored LinuxCNC interpreter source set used by the native minimal
interpreter harness. It loads the module in Node, runs the first WASM
interpreter fixture group through `Interp::execute()`, and compares emitted
canonical events plus required LinuxCNC `_setup` state readback with the
matching files in `tests/fixtures/canon/`. It also writes selected G-code
fixtures into the Emscripten filesystem and runs them through LinuxCNC
interpreter harness. It loads the module in Node through
`runtime/sdk/src/index.js`, runs the first WASM interpreter fixture
group through `Interp::execute()`, and compares emitted canonical events plus
required LinuxCNC `_setup` state readback with the matching files in
`tests/fixtures/canon/`. It also writes selected G-code fixtures into the
Emscripten filesystem through the SDK and runs them through LinuxCNC
`Interp::open()`, `Interp::read()`, and `Interp::execute()` to validate the
file execution path.
@@ -90,15 +98,24 @@ targets. It also validates the host-side session snapshot JSON envelope and
round-trip store plus pure-text machine file and G-code stores without
defining CNC machine-state or file-format semantics.
The browser smoke script serves `wasm-port/` over localhost and runs Chromium
headless against a test page that imports the JS SDK, loads the INI WASM
module, queries vendored LinuxCNC INI parsing through the SDK, and performs an
OPFS text-file, generic session snapshot, machine file, and G-code text
round trip.
The browser INI/OPFS smoke script serves `wasm-port/` over localhost and runs
Chromium headless against a test page that imports the JS SDK, loads the INI
WASM module, queries vendored LinuxCNC INI parsing through the SDK, and
performs an OPFS text-file, generic session snapshot, machine file, and G-code
text round trip.
The browser interpreter smoke script serves `wasm-port/` over localhost and
runs Chromium headless against a test page that loads the interpreter-core
WASM module through `runtime/sdk/src/index.js`, writes no CNC
behavior in JavaScript, and verifies existing canonical fixtures through the
exported C ABI backed by vendored LinuxCNC `Interp::execute()` and
`Interp::open()`/`read()`/`execute()` paths, including the INI-aware
named-parameter file path and negative interpreter fixtures with expected
error text plus absent canonical motion output.
The aggregate host smoke script builds the INI and interpreter-core WASM
artifacts once, then runs the Node WASM smokes, the Node OPFS mock smoke, and
the Chromium browser smoke.
the Chromium browser smokes.
## Source Coverage
@@ -147,9 +164,10 @@ The validation fails if:
| Harness | Purpose |
| --- | --- |
| `tests/wasm/node/verify_ini_wasm.sh` | Validates the browser-facing INI WASM module can be built from vendored LinuxCNC `inifile.cc`, loaded through the JS SDK in Node, and queried through the exported C ABI. |
| `tests/wasm/node/verify_interp_wasm.sh` | Validates the initial interpreter-core WASM module can be built from vendored LinuxCNC interpreter source, run the first fixture group through `Interp::execute()` and selected file fixtures through `Interp::open()`/`read()`/`execute()`, and match the native canonical event plus required state readback fixtures. |
| `tests/wasm/node/verify_interp_wasm.sh` | Validates the initial interpreter-core WASM module can be built from vendored LinuxCNC interpreter source, loaded through the interpreter JS SDK, run the first fixture group through `Interp::execute()` and selected file fixtures through `Interp::open()`/`read()`/`execute()`, and match the native canonical event plus required state readback fixtures. |
| `tests/opfs/node/verify_file_service.sh` | Validates the host-owned OPFS text-file adapter, path model, session snapshot store, machine file store, and G-code text store used by the browser INI panel without moving file persistence into the WASM core. |
| `tests/browser/verify_ini_panel_browser.sh` | Validates the INI SDK, WASM module loading, OPFS text-file round trip, generic session snapshot round trip, machine file text round trip, and G-code text round trip in a real browser runtime. |
| `tests/browser/verify_interp_browser.sh` | Validates the interpreter-core WASM module loads through the interpreter JS SDK in a real browser runtime and runs selected positive and negative canonical fixtures through vendored LinuxCNC `Interp::execute()` plus `Interp::open()`/`read()`/`execute()` via the exported C ABI. |
| `tests/host/verify_host_smokes.sh` | Runs the current host-side Node, WASM interpreter-core, OPFS, and browser smoke validation with shared WASM builds. |
## Fixture Coverage
@@ -206,12 +224,127 @@ plus the `g1_zero_feed`, `arc_radius_mismatch`, `arc_zero_radius`,
`cutter_comp_plane_change`, `g53_incremental`, `namedparam_readonly`,
`numbered_param_readonly`, `tool_not_found`, and
`tool_length_offset_not_found` negative fixtures. The WASM interpreter file
path additionally covers the same canonical-event fixture group except
`namedparam_semantics` and `position_params`, plus `file_open_reset`,
`percent_file_finish`, and `oword_subroutine`. OPFS validation is limited to
the JavaScript host-boundary adapter plus the INI browser smoke harness. Full
browser coverage, full SDK coverage, and full machine-session validation remain
future work.
path additionally covers the same canonical-event fixture group, plus
`namedparam_semantics` through the INI-aware file execution ABI,
`file_open_reset`, `percent_file_finish`, and `oword_subroutine`.
`position_params` uses a dedicated file-path expectation under
`tests/fixtures/canon_file/` because LinuxCNC file execution advances the
post-execute position parameters differently than the line-by-line MDI smoke.
OPFS validation is limited to the JavaScript host-boundary adapter plus the INI
browser smoke harness. Full browser coverage, full SDK coverage, and full
machine-session validation remain future work.
## WASM/Browser Fixture Matrix
Node WASM `Interp::execute()` coverage currently includes:
- `minimal_linear`
- `arc_semantics`
- `length_units`
- `modal_incremental`
- `plane_selection`
- `coordinate_offsets`
- `g53_machine_coordinates`
- `feed_control_modes`
- `position_params`
- `probe_semantics`
- `spindle_orient`
- `comment_logging`
- `numbered_params`
- `tool_semantics`
- `tool_table_setup`
- `tool_reload`
- `canned_cycles`
- `cutter_comp_motion`
- `threading_sync`
- `nurbs_g5_semantics`
- `nurbs_g6_semantics`
- `state_tag_motion`
- `canon_runtime_edges`
- `program_end_modal_reset`
- `namedparam_semantics` through the INI-aware program ABI
Node WASM file-path coverage currently includes:
- `minimal_linear`
- `arc_semantics`
- `length_units`
- `modal_incremental`
- `plane_selection`
- `coordinate_offsets`
- `g53_machine_coordinates`
- `feed_control_modes`
- `probe_semantics`
- `spindle_orient`
- `comment_logging`
- `numbered_params`
- `tool_semantics`
- `tool_table_setup`
- `tool_reload`
- `canned_cycles`
- `cutter_comp_motion`
- `threading_sync`
- `nurbs_g5_semantics`
- `nurbs_g6_semantics`
- `state_tag_motion`
- `canon_runtime_edges`
- `program_end_modal_reset`
- `file_open_reset`
- `percent_file_finish`
- `oword_subroutine`
- `position_params` through the dedicated `canon_file/` expectation
- `namedparam_semantics` through the INI-aware file ABI
Browser interpreter `Interp::execute()` coverage currently includes:
- `minimal_linear`
- `arc_semantics`
- `length_units`
- `modal_incremental`
- `plane_selection`
- `coordinate_offsets`
- `g53_machine_coordinates`
- `feed_control_modes`
- `canned_cycles`
- `numbered_params`
- `comment_logging`
- `tool_semantics`
- `tool_table_setup`
- `probe_semantics`
- `spindle_orient`
- `cutter_comp_motion`
- `threading_sync`
- `nurbs_g5_semantics`
- `nurbs_g6_semantics`
- `state_tag_motion`
- `canon_runtime_edges`
- `tool_reload`
- `program_end_modal_reset`
Browser interpreter negative coverage currently includes every fixture under
`tests/fixtures/gcode_errors/`:
- `g1_zero_feed`
- `arc_radius_mismatch`
- `arc_zero_radius`
- `g53_incremental`
- `cutter_comp_plane_change`
- `namedparam_readonly`
- `numbered_param_readonly`
- `tool_length_offset_not_found`
- `tool_not_found`
Browser interpreter file-path coverage currently includes:
- `position_params` through the dedicated `canon_file/` expectation
- `file_open_reset`
- `percent_file_finish`
- `oword_subroutine`
- `namedparam_semantics` through the INI-aware file ABI
All current positive G-code fixtures have browser interpreter smoke coverage
through either `Interp::execute()`, the file-path ABI, or the INI-aware
file-path ABI.
The current fixture expectations validate standalone behavior against both the
vendored LinuxCNC source path and an upstream `rs274` side-by-side baseline for

View File

@@ -49,7 +49,8 @@ semantic rewrites:
- Do not edit `../linuxcnc/`.
- Do not patch vendored files without adding a patch under `patches/` and
documenting the reason.
- Do not add standalone `Interp::convert_g()`.
- Do not add standalone `Interp::...` member definitions outside the
documented Python/remap runtime-edge stubs.
- Do not add `.c` or `.cc` manifest files without a source compile probe.
- Do not sync from a different upstream commit without updating
`tools/upstream-baseline.txt` and `docs/scope-and-baseline.md`.
@@ -58,8 +59,10 @@ semantic rewrites:
- No browser/full-core WASM parity tests yet. The INI parser now has Node and
Chromium smoke harnesses against vendored LinuxCNC `inifile.cc`.
- JS SDK validation is currently limited to the INI WASM wrapper around
vendored LinuxCNC `inifile.cc`.
- JS SDK validation now covers the INI WASM wrapper around vendored LinuxCNC
`inifile.cc` and the interpreter-core SDK wrapper around the existing
exported C ABI. The interpreter SDK only manages strings, Emscripten file
writes, and calls into vendored LinuxCNC execution paths.
- OPFS validation covers a Node mock of the file-service adapter, the
host-side path model, generic session snapshot storage, pure-text machine
file and G-code storage, and a Chromium localhost round trip for those

View File

@@ -888,14 +888,20 @@ Keep these documents under `wasm-port/docs/`:
## Immediate Next Step
Continue expanding the standalone interpreter core from the verified minimal
traverse path:
Continue from the current verified extracted-core baseline without adding
project-authored CNC semantics:
1. keep `convert_g()` execution on vendored LinuxCNC interpreter conversion
code and reject any new standalone `Interp::convert_g()` implementation.
2. identify and shim the native runtime symbols blocking direct compilation of
`interp_convert.cc`, `interp_execute.cc`, and related interpreter files.
3. keep fixture coverage as regression protection while deleting temporary
hand-written semantics.
4. keep all source changes inside `wasm-port/` and leave `../linuxcnc/`
read-only.
1. Keep all `Interp::...` interpreter member behavior on vendored LinuxCNC
source. Standalone code may only provide documented runtime-edge stubs such
as the current Python/remap boundary.
2. Expand WASM interpreter coverage by routing more existing native fixture
paths through `runtime/core/linuxcnc_wrap/linuxcnc_interp_wasm.cpp`, using
the same vendored interpreter source set as the native harness.
3. Promote remaining standalone-only fixture expectations to native LinuxCNC
baselines where possible, especially adapter-heavy paths such as INI/HAL
named parameters, tool-change host state, and richer machine session state.
4. Move browser-facing work through SDK and OPFS adapters only after the core
behavior is validated against native LinuxCNC or vendored-source harnesses.
5. Before adding any CNC feature, update `tools/source-manifest.txt`, extract
the LinuxCNC source file, add a source probe or harness, and document the
reuse boundary in `docs/source-reuse-map.md`.

View File

@@ -25,13 +25,15 @@ Current validation is intentionally mechanical:
- `tests/native/verify_native_probes.sh` checks that every manifest `.c` and
`.cc` file has a matching source probe in `build/native/source-probes.tsv`.
- `tools/verify_no_standalone_cnc_semantics.sh` rejects standalone
`Interp::convert_g()` definitions outside `vendor/linuxcnc/`.
`Interp::...` member definitions outside `vendor/linuxcnc/`, except for the
documented Python/remap runtime-edge stubs in
`runtime/core/linuxcnc_wrap/linuxcnc_interp_edge_stubs.cpp`.
## Reuse Matrix
| Capability | LinuxCNC source files | Port classification | Standalone boundary | Current validation |
| --- | --- | --- | --- | --- |
| INI parsing | `src/emc/ini/inifile.cc`, `inifile.h`, `inifile.hh` | Copy unchanged | Native file IO remains LinuxCNC-style in the vendored parser; browser OPFS integration remains outside this layer; `runtime/sdk/src/linuxcnc-ini.js` only wraps the exported WASM C ABI | Vendor byte sync, `linuxcnc_ini_probe`, `linuxcnc_inifile_source_probe`, `tests/wasm/node/verify_ini_wasm.sh`, `tests/browser/verify_ini_panel_browser.sh`, `tests/host/verify_host_smokes.sh` |
| INI parsing | `src/emc/ini/inifile.cc`, `inifile.h`, `inifile.hh` | Copy unchanged | Native file IO remains LinuxCNC-style in the vendored parser; browser OPFS integration remains outside this layer; `runtime/sdk/src/index.js` exports the INI SDK wrapper around the generated WASM C ABI | Vendor byte sync, `linuxcnc_ini_probe`, `linuxcnc_inifile_source_probe`, `tests/wasm/node/verify_ini_wasm.sh`, `tests/browser/verify_ini_panel_browser.sh`, `tests/host/verify_host_smokes.sh` |
| RTAPI compatibility headers | `src/rtapi/rtapi_*.h` in the manifest | Copy unchanged plus standalone shim include path | `runtime/core/shims/rtapi.h` supplies the minimal standalone RTAPI surface needed by vendored code | Vendor byte sync, compile coverage through dependent source probes |
| Canon/NML-facing interpreter types | `src/emc/nml_intf/canon*.hh`, `emctool.h`, `interp_return.hh`, `motion_types.h`, `emcpose.*`, `emcpos.h`, `debugflags.h`, `src/emc/linuxcnc.h` | Copy unchanged plus narrow standalone status shim | NML transport is not ported; `runtime/core/shims/nml_intf/emc.hh` exposes only the `emcStatus` machine-units status edge currently needed by vendored interpreter conversion and initialization code | Vendor byte sync, dependent source probes, `linuxcnc_emc_status_probe`, `linuxcnc_tp_api_probe`, interpreter harnesses |
| Motion state headers | `src/emc/motion/state_tag.h`, `emcmotcfg.h`, `simple_tp.h`, `motion.h`, `mot_priv.h`, `axis.h` | Copy unchanged | Realtime motion process is not ported; standalone probes seed the small motion status/config state required by TP calls | Vendor byte sync, `linuxcnc_tp_api_probe` |
@@ -68,9 +70,11 @@ Current validation is intentionally mechanical:
userspace genser flows are not yet established.
- Cutter compensation positive motion and negative interpreter paths are
fixture-covered through vendored `interp_convert.cc` and `interp_queue.cc`.
- Browser/WASM C ABI and JS SDK layers are not yet built for the full
interpreter/planner core. The INI parser has a minimal JS SDK wrapper and
Node/browser WASM smoke harnesses.
- Browser/WASM C ABI and JS SDK layers are now present for the INI parser and
the current interpreter-core smoke scope. The interpreter SDK is a thin
allocation, filesystem, and C ABI wrapper over vendored LinuxCNC execution
paths; it does not define G-code semantics. Full planner/session SDK
coverage remains future work.
- OPFS persistence is connected to the INI panel through the host-side
`runtime/opfs/file-service.js` adapter. `runtime/opfs/path-model.js` now
defines paths for INI, tool table, parameter file, G-code program,