按建议,继续完成后续工作

结论:已新增 INI WASM Node smoke 验证,确认 vendored LinuxCNC inifile.cc 构建出的 WASM 模块可通过导出 C ABI 查询 INI 内容,并同步更新兼容性与漂移文档。
This commit is contained in:
2026-06-08 00:15:50 +08:00
parent 0b70bb0aa8
commit 0a8bf7d5e2
8 changed files with 116 additions and 9 deletions

View File

@@ -6,12 +6,18 @@ This document records how the standalone LinuxCNC WASM port currently proves
that migrated behavior remains tied to LinuxCNC source code and fixture that migrated behavior remains tied to LinuxCNC source code and fixture
semantics. semantics.
The primary validation command is: The primary native validation command is:
```bash ```bash
wasm-port/tests/native/verify_native_probes.sh wasm-port/tests/native/verify_native_probes.sh
``` ```
The current WASM smoke validation command is:
```bash
wasm-port/tests/wasm/node/verify_ini_wasm.sh
```
## Validation Chain ## Validation Chain
The native validation script runs these checks in order: The native validation script runs these checks in order:
@@ -35,6 +41,11 @@ The native validation script runs these checks in order:
Checks probe exit codes, source-probe coverage, harness stdout, canonical Checks probe exit codes, source-probe coverage, harness stdout, canonical
fixture events, and expected error behavior. fixture events, and expected error behavior.
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 in Node and verifies `lcini_get_string()` against an in-memory INI file
written to the Emscripten filesystem.
## Source Coverage ## Source Coverage
Every `.c` and `.cc` entry in `tools/source-manifest.txt` must have a Every `.c` and `.cc` entry in `tools/source-manifest.txt` must have a
@@ -77,6 +88,12 @@ The validation fails if:
| `linuxcnc_genhex_kinematics_probe` | Validates vendored LinuxCNC generic hexapod inverse/forward behavior, including the switchkins iterative-forward warmup path. | | `linuxcnc_genhex_kinematics_probe` | Validates vendored LinuxCNC generic hexapod inverse/forward behavior, including the switchkins iterative-forward warmup path. |
| `linuxcnc_pentakins_kinematics_probe` | Validates vendored LinuxCNC pentapod inverse/forward pose round-trip behavior. | | `linuxcnc_pentakins_kinematics_probe` | Validates vendored LinuxCNC pentapod inverse/forward pose round-trip behavior. |
## Current WASM Harnesses
| 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 in Node, and queried through the exported C ABI. |
## Fixture Coverage ## Fixture Coverage
Positive G-code fixtures currently cover: Positive G-code fixtures currently cover:
@@ -118,8 +135,9 @@ Negative fixtures currently cover:
## Validation Boundaries ## Validation Boundaries
Current validation is native-only. WASM, browser, SDK, OPFS, and full Current full-core validation is native-only. WASM validation is limited to the
machine-session validation remain future work. INI parser smoke harness. Browser, SDK, OPFS, and full machine-session
validation remain future work.
The current fixture expectations validate standalone behavior against both the The current fixture expectations validate standalone behavior against both the
vendored LinuxCNC source path and an upstream `rs274` side-by-side baseline for vendored LinuxCNC source path and an upstream `rs274` side-by-side baseline for

View File

@@ -56,7 +56,8 @@ semantic rewrites:
## Known Gaps ## Known Gaps
- No browser/WASM parity tests yet. - No browser/full-core WASM parity tests yet. The INI parser now has a Node
WASM smoke harness against vendored LinuxCNC `inifile.cc`.
- No JS SDK validation yet. - No JS SDK validation yet.
- No OPFS persistence validation yet. - No OPFS persistence validation yet.
- Identity/trivial, `5axiskins`, TRT `xyzac`/`xyzbc`, delta, SCARA, PUMA, - Identity/trivial, `5axiskins`, TRT `xyzac`/`xyzbc`, delta, SCARA, PUMA,

View File

@@ -31,7 +31,7 @@ Current validation is intentionally mechanical:
| Capability | LinuxCNC source files | Port classification | Standalone boundary | Current validation | | 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 | Vendor byte sync, `linuxcnc_ini_probe`, `linuxcnc_inifile_source_probe` | | 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 | Vendor byte sync, `linuxcnc_ini_probe`, `linuxcnc_inifile_source_probe`, `tests/wasm/node/verify_ini_wasm.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 | | 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 | | 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` | | 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` |
@@ -69,7 +69,7 @@ Current validation is intentionally mechanical:
- Cutter compensation positive motion and negative interpreter paths are - Cutter compensation positive motion and negative interpreter paths are
fixture-covered through vendored `interp_convert.cc` and `interp_queue.cc`. 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 - Browser/WASM C ABI and JS SDK layers are not yet built for the full
interpreter/planner core. interpreter/planner core. The INI parser has a Node WASM smoke harness.
- OPFS persistence is not yet connected to INI, tool table, parameter file, or - OPFS persistence is not yet connected to INI, tool table, parameter file, or
G-code program loading. G-code program loading.
- Native LinuxCNC GUI code remains out of scope for implementation. - Native LinuxCNC GUI code remains out of scope for implementation.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,4 @@
{
"private": true,
"type": "module"
}

View File

@@ -0,0 +1,77 @@
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname, resolve } from "node:path";
import assert from "node:assert/strict";
import createLinuxCncIniModule from "../../../runtime/ui/ini-panel/linuxcnc_ini.js";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const rootDir = resolve(__dirname, "../../..");
const wasmPath = resolve(rootDir, "runtime/ui/ini-panel/linuxcnc_ini.wasm");
const mod = await createLinuxCncIniModule({
wasmBinary: readFileSync(wasmPath),
print() {},
printErr(message) {
console.error(message);
},
});
function allocCString(value) {
const bytes = mod.lengthBytesUTF8(value) + 1;
const ptr = mod._malloc(bytes);
mod.stringToUTF8(value, ptr, bytes);
return ptr;
}
function queryIni(path, section, tag) {
const pathPtr = allocCString(path);
const sectionPtr = allocCString(section);
const tagPtr = allocCString(tag);
const outSize = 256;
const outPtr = mod._malloc(outSize);
try {
const rc = mod._lcini_get_string(pathPtr, sectionPtr, tagPtr, outPtr, outSize);
return { rc, value: rc === 0 ? mod.UTF8ToString(outPtr) : null };
} finally {
mod._free(pathPtr);
mod._free(sectionPtr);
mod._free(tagPtr);
mod._free(outPtr);
}
}
mod.FS.mkdir("/work");
mod.FS.writeFile(
"/work/node-smoke.ini",
`[EMC]
MACHINE = wasm-node-smoke
[TRAJ]
LINEAR_UNITS = mm
COORDINATES = X Y Z A B
[KINS]
KINEMATICS = xyzbc-trt-kins
JOINTS = 5
`,
{ encoding: "utf8" },
);
assert.deepEqual(queryIni("/work/node-smoke.ini", "EMC", "MACHINE"), {
rc: 0,
value: "wasm-node-smoke",
});
assert.deepEqual(queryIni("/work/node-smoke.ini", "TRAJ", "LINEAR_UNITS"), {
rc: 0,
value: "mm",
});
assert.deepEqual(queryIni("/work/node-smoke.ini", "KINS", "KINEMATICS"), {
rc: 0,
value: "xyzbc-trt-kins",
});
assert.notEqual(queryIni("/work/node-smoke.ini", "TRAJ", "MISSING").rc, 0);
console.log("ini_wasm_node_smoke=ok");

View File

@@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/../../.." && pwd)"
"$ROOT_DIR/tools/build_ini_panel.sh"
node "$ROOT_DIR/tests/wasm/node/verify_ini_wasm.mjs"

View File

@@ -16,7 +16,7 @@ emcc \
-o "$OUT_DIR/linuxcnc_ini.js" \ -o "$OUT_DIR/linuxcnc_ini.js" \
-s MODULARIZE=1 \ -s MODULARIZE=1 \
-s EXPORT_ES6=1 \ -s EXPORT_ES6=1 \
-s ENVIRONMENT=web \ -s ENVIRONMENT=web,node \
-s ALLOW_MEMORY_GROWTH=1 \ -s ALLOW_MEMORY_GROWTH=1 \
-s NO_EXIT_RUNTIME=1 \ -s NO_EXIT_RUNTIME=1 \
-s FORCE_FILESYSTEM=1 \ -s FORCE_FILESYSTEM=1 \