From a0f622890871a7360a2273ffa7678313e981765f Mon Sep 17 00:00:00 2001 From: cnc Date: Thu, 4 Jun 2026 15:54:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=82=E8=80=83=E6=89=80=E6=9C=89=E5=88=86?= =?UTF-8?q?=E7=BB=84=EF=BC=8C=E5=AE=8C=E6=88=90=E5=B0=BD=E9=87=8F=E5=A4=9A?= =?UTF-8?q?=E7=9A=84=E5=86=85=E5=AE=B9=E3=80=82=E7=A6=81=E6=AD=A2=E9=A1=BA?= =?UTF-8?q?=E6=89=8B=E6=89=A9=E5=8A=9F=E8=83=BD=20smoke?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 结论:补齐 LinuxCNC WASM blocker source-map,锁定 RS274/WASM manifest、Python/Boost.Python、dlopen、tooldata mmap、native-fs 分类与 wasm-safe shim replacement;未扩展 smoke 行为。验证通过:./check-linuxcnc-wasm-blockers-source-map.sh linuxcnc-rs274-wasm-source-files.txt、./test-linuxcnc-wasm-blockers.sh linuxcnc-rs274-wasm-source-files.txt、./test-native.sh、./test-linuxcnc-source-link.sh、CNC_SIM_ALL_NATIVE_GUARDRAILS_ONLY=1 ./test-all-native.sh、./test-linuxcnc-source-syntax.sh、./test-linuxcnc-wasm-cmake-safe-probe.sh。 --- check-linuxcnc-wasm-blockers-source-map.sh | 137 +++++++++++++++++++++ docs/linuxcnc-wasm-blockers-source-map.md | 77 ++++++++++++ test-all-native.sh | 6 + 3 files changed, 220 insertions(+) create mode 100755 check-linuxcnc-wasm-blockers-source-map.sh create mode 100644 docs/linuxcnc-wasm-blockers-source-map.md diff --git a/check-linuxcnc-wasm-blockers-source-map.sh b/check-linuxcnc-wasm-blockers-source-map.sh new file mode 100755 index 0000000..3c8669e --- /dev/null +++ b/check-linuxcnc-wasm-blockers-source-map.sh @@ -0,0 +1,137 @@ +#!/usr/bin/env bash +set -euo pipefail + +cd "$(dirname "$0")" + +# LinuxCNC source basis: this guard ties the documented WASM blocker map to +# LinuxCNC RS274/Python/remap/tooldata sources, the rs274 WASM manifest, and +# wasm-safe shim replacement sources. It validates source coverage only; it +# does not add CNC behavior or expand smoke parsing. +linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc} +manifest=${1:-linuxcnc-rs274-wasm-source-files.txt} + +LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh "$manifest" +linuxcnc_root=$(cd "$linuxcnc_root" && pwd) + +grep -F 'LinuxCNC source basis: this blocker scan is constrained to the RS274/WASM' \ + analyze-linuxcnc-wasm-blockers.sh >/dev/null +grep -F 'blocked replacement is not in wasm shim build set' \ + analyze-linuxcnc-wasm-blockers.sh >/dev/null +grep -F 'shim_source_output=$(./list-linuxcnc-wasm-safe-shims.sh)' \ + analyze-linuxcnc-wasm-blockers.sh >/dev/null +grep -F 'LinuxCNC source basis: this guardrail locks the blocker categories reported' \ + test-linuxcnc-wasm-blockers.sh >/dev/null +grep -F 'Cache wasm blocker analyzer output' docs/linuxcnc-source-policy.md >/dev/null + +grep -F '#include ' "$linuxcnc_root/src/emc/rs274ngc/gcodemodule.cc" >/dev/null +grep -F 'PyInit_gcode' "$linuxcnc_root/src/emc/rs274ngc/gcodemodule.cc" >/dev/null +grep -F '#include ' "$linuxcnc_root/src/emc/rs274ngc/interpmodule.cc" >/dev/null +grep -F '#include "pythonplugin/python_plugin.hh"' "$linuxcnc_root/src/emc/rs274ngc/interp_python.cc" >/dev/null +grep -F 'dlopen' "$linuxcnc_root/src/emc/rs274ngc/interp_base.cc" >/dev/null +grep -F 'opendir(direct)' "$linuxcnc_root/src/emc/rs274ngc/interp_o_word.cc" >/dev/null +grep -F 'readdir(aDir)' "$linuxcnc_root/src/emc/rs274ngc/interp_o_word.cc" >/dev/null +grep -F '#define TOOL_MMAP_FILENAME ".tool.mmap"' "$linuxcnc_root/src/emc/tooldata/tooldata_mmap.cc" >/dev/null +grep -F 'int tool_mmap_creator(' "$linuxcnc_root/src/emc/tooldata/tooldata_mmap.cc" >/dev/null + +python3 - "$linuxcnc_root" "$manifest" <<'PY' +from pathlib import Path +import re +import subprocess +import sys + +linuxcnc_root = Path(sys.argv[1]) +manifest = Path(sys.argv[2]) +source_map = Path("docs/linuxcnc-wasm-blockers-source-map.md").read_text(encoding="utf-8") +manifest_lines = [ + line for line in manifest.read_text(encoding="utf-8").splitlines() + if line and not line.startswith("#") +] +manifest_counts = {"core": 0, "blocked": 0, "header": 0, "blocked-header": 0, "metadata": 0} +for line in manifest_lines: + group = line.split(":", 1)[0] + if group not in manifest_counts: + raise SystemExit(f"unexpected WASM manifest group in blocker source map guard: {group}") + manifest_counts[group] += 1 +for group, count in manifest_counts.items(): + if f"| `{group}` | {count} |" not in source_map: + raise SystemExit(f"docs/linuxcnc-wasm-blockers-source-map.md count mismatch for {group}") + +output = subprocess.check_output( + ["./analyze-linuxcnc-wasm-blockers.sh", str(manifest)], + text=True, + env={"LINUXCNC_ROOT": str(linuxcnc_root)}, +) +sections = {} +current = None +for line in output.splitlines(): + if line.startswith("[") and line.endswith("]"): + current = line[1:-1] + sections[current] = [] + elif current and line: + sections[current].append(line) + +expected_counts = { + "manifest-core": "core=26", + "manifest-blocked": "blocked=9", + "python": 8, + "tooldata": 1, + "native-backend": 1, + "native-fs": 1, + "blocked-replacements": 9, + "core-python-shimmed": 6, + "core-dlopen-shimmed": 1, + "core-tooldata-shimmed": 1, + "core-tooldata-users-shimmed": 2, + "core-native-fs-shimmed": 16, +} +manifest_section = sections.get("manifest", []) +if expected_counts["manifest-core"] not in manifest_section: + raise SystemExit("WASM blocker analyzer core count changed") +if expected_counts["manifest-blocked"] not in manifest_section: + raise SystemExit("WASM blocker analyzer blocked count changed") +for section, count in expected_counts.items(): + if section.startswith("manifest-"): + continue + entries = [entry for entry in sections.get(section, []) if entry != "(none)"] + if len(entries) != count: + raise SystemExit(f"WASM blocker analyzer section {section} count changed: {len(entries)}") + if f"| `{section}` | {count} |" not in source_map: + raise SystemExit(f"docs/linuxcnc-wasm-blockers-source-map.md analyzer count mismatch for {section}") +if sections.get("dlopen") != ["(none)"]: + raise SystemExit("blocked dlopen section is no longer empty") +if sections.get("tooldata-users") != ["(none)"]: + raise SystemExit("blocked tooldata-users section is no longer empty") + +required_entries = [ + "src/emc/rs274ngc/gcodemodule.cc", + "src/emc/rs274ngc/interpmodule.cc", + "src/emc/tooldata/tooldata_mmap.cc", + "src/emc/rs274ngc/interp_base.cc", + "src/emc/rs274ngc/interp_o_word.cc", + "src/emc/rs274ngc/rs274ngc_pre.cc", + "src/emc/tooldata/tooldata_mmap.cc -> core/wasm_shims/tooldata/tooldata_mmap_backend.cc", + "src/emc/rs274ngc/gcodemodule.cc -> core/wasm_shims/linuxcnc_runtime_shim.cc", + "src/emc/rs274ngc/pyparamclass.cc -> core/wasm_shims/python_c_api_shim.cc", +] +for entry in required_entries: + if entry not in output: + raise SystemExit(f"WASM blocker analyzer output missing required entry: {entry}") + if entry not in source_map: + raise SystemExit(f"docs/linuxcnc-wasm-blockers-source-map.md missing required entry: {entry}") + +shim_paths = set(Path(line).as_posix() for line in subprocess.check_output( + ["./list-linuxcnc-wasm-safe-shims.sh"], + text=True, +).splitlines() if line) +for replacement in re.findall(r"-> (core/wasm_shims/[^\s]+)", output): + if replacement not in shim_paths: + raise SystemExit(f"blocked replacement is absent from wasm-safe shim set: {replacement}") +for phrase in [ + "does not add CNC behavior", + "must not become smoke parser behavior", + "blocked `dlopen` and blocked tooldata-users remain empty", + "Python/Boost.Python remap paths remain tracked blockers", +]: + if phrase not in source_map: + raise SystemExit(f"docs/linuxcnc-wasm-blockers-source-map.md missing boundary phrase: {phrase}") +PY diff --git a/docs/linuxcnc-wasm-blockers-source-map.md b/docs/linuxcnc-wasm-blockers-source-map.md new file mode 100644 index 0000000..813dd97 --- /dev/null +++ b/docs/linuxcnc-wasm-blockers-source-map.md @@ -0,0 +1,77 @@ +# LinuxCNC WASM blockers source map + +This map records the source basis for the WASM blocker categories used by +`analyze-linuxcnc-wasm-blockers.sh` and `test-linuxcnc-wasm-blockers.sh`. It is +a source-link/build guard only; it does not add CNC behavior and must not become smoke parser behavior. + +## LinuxCNC Source Basis + +- `src/emc/rs274ngc/gcodemodule.cc`, `canonmodule.cc`, `interpmodule.cc`, and + `py*.cc` provide the Python and Boost.Python module binding blockers. +- `src/emc/rs274ngc/interp_python.cc`, `interp_remap.cc`, + `interp_namedparams.cc`, `interp_o_word.cc`, `interp_setup.cc`, and + `rs274ngc_pre.cc` keep Python/Boost.Python remap paths as shimmed core + sources. +- `src/emc/rs274ngc/interp_base.cc` is the core source that still carries + `dlopen` use satisfied by the wasm dlfcn shim. +- `src/emc/tooldata/tooldata_mmap.cc` is the native mmap backend blocker + replaced by the wasm-safe tooldata mmap backend shim. +- `src/emc/rs274ngc/interp_o_word.cc` uses native directory traversal for + O-word subroutine lookup; browser persistence remains OPFS-only. + +## Manifest Coverage + +| Manifest group | Count | Role | +| --- | ---: | --- | +| `core` | 26 | LinuxCNC RS274/tooldata/INI/NML sources compiled or shim-satisfied by WASM probes. | +| `blocked` | 9 | LinuxCNC Python binding and native tooldata sources tracked but replaced for WASM. | +| `header` | 26 | LinuxCNC headers needed by the WASM-safe source probes and shims. | +| `blocked-header` | 1 | Boost.Python helper header tracked as blocked browser API surface. | +| `metadata` | 15 | LinuxCNC build/source-basis files for shim coverage. | + +## Analyzer Coverage + +| Analyzer section | Count | Boundary | +| --- | ---: | --- | +| `python` | 8 | Blocked Python/Boost.Python module sources. | +| `dlopen` | 0 | blocked `dlopen` and blocked tooldata-users remain empty. | +| `tooldata` | 1 | Native tooldata mmap blocker. | +| `tooldata-users` | 0 | Blocked tooldata user sources remain empty. | +| `native-backend` | 1 | Native backend source excluded from browser linking. | +| `native-fs` | 1 | Native filesystem blocker excluded from browser linking. | +| `blocked-replacements` | 9 | Blocked LinuxCNC sources mapped to wasm-safe shim files. | +| `core-python-shimmed` | 6 | Core LinuxCNC Python/remap users compiled with Python/Boost.Python shims. | +| `core-dlopen-shimmed` | 1 | Core LinuxCNC `dlopen` user compiled with dlfcn shim. | +| `core-tooldata-shimmed` | 1 | Core LinuxCNC tooldata source compiled with wasm tooldata shims. | +| `core-tooldata-users-shimmed` | 2 | Core RS274/NML users of tooldata declarations. | +| `core-native-fs-shimmed` | 16 | Core sources with native filesystem includes or calls covered by WASM shims. | + +Required replacement examples: + +- `src/emc/tooldata/tooldata_mmap.cc -> core/wasm_shims/tooldata/tooldata_mmap_backend.cc` +- `src/emc/rs274ngc/gcodemodule.cc -> core/wasm_shims/linuxcnc_runtime_shim.cc` +- `src/emc/rs274ngc/pyparamclass.cc -> core/wasm_shims/python_c_api_shim.cc` + +Required tracked core examples: + +- `src/emc/rs274ngc/gcodemodule.cc` +- `src/emc/rs274ngc/interpmodule.cc` +- `src/emc/tooldata/tooldata_mmap.cc` +- `src/emc/rs274ngc/interp_base.cc` +- `src/emc/rs274ngc/interp_o_word.cc` +- `src/emc/rs274ngc/rs274ngc_pre.cc` + +## Checks + +Run: + +```bash +./check-linuxcnc-wasm-blockers-source-map.sh +./test-linuxcnc-wasm-blockers.sh linuxcnc-rs274-wasm-source-files.txt +./test-native.sh +./test-linuxcnc-source-link.sh +``` + +`check-linuxcnc-wasm-blockers-source-map.sh` keeps this document, the +RS274/WASM manifest, LinuxCNC source anchors, analyzer output, and wasm-safe +shim replacement set synchronized. Python/Boost.Python remap paths remain tracked blockers until they are ported, wrapped, or replaced by source-backed browser-safe LinuxCNC adaptations. diff --git a/test-all-native.sh b/test-all-native.sh index 14b3413..c3b4786 100755 --- a/test-all-native.sh +++ b/test-all-native.sh @@ -150,6 +150,7 @@ grep -F './check-linuxcnc-opfs-source-map.sh' test-native.sh >/dev/null grep -F 'LinuxCNC source basis: this guard ties generated switchkins/remap aliases' check-linuxcnc-switchkins-remap-source-map.sh >/dev/null grep -F './check-linuxcnc-switchkins-remap-source-map.sh' test-native.sh >/dev/null grep -F './check-linuxcnc-switchkins-remap-source-map.sh' test-linuxcnc-source-link.sh >/dev/null +grep -F 'LinuxCNC source basis: this guard ties the documented WASM blocker map' check-linuxcnc-wasm-blockers-source-map.sh >/dev/null grep -F 'LinuxCNC source basis: the cached input checker keys check-linuxcnc-inputs.sh' check-linuxcnc-inputs-cached.sh >/dev/null grep -F 'LinuxCNC source basis: switchkins/remap table validation derives M428/M429/M430' check-linuxcnc-switchkins-remap-table.sh >/dev/null grep -F 'LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh "$manifest" --require-kinematics-complete' check-linuxcnc-switchkins-remap-table.sh >/dev/null @@ -222,6 +223,9 @@ grep -F 'LinuxCNC switchkins/remap source map' docs/linuxcnc-switchkins-remap-so grep -F '| `core/src/linuxcnc_switchkins_remap_table.inc` | 177 | Generated switchkins aliases from LinuxCNC INI/HAL/remap sources. |' docs/linuxcnc-switchkins-remap-source-map.md >/dev/null grep -F '[EMCIO] TOOL_TABLE` entries are source coverage only' docs/linuxcnc-switchkins-remap-source-map.md >/dev/null grep -F './check-linuxcnc-switchkins-remap-source-map.sh' test-linuxcnc-source-link.sh >/dev/null +grep -F 'LinuxCNC WASM blockers source map' docs/linuxcnc-wasm-blockers-source-map.md >/dev/null +grep -F '| `blocked-replacements` | 9 | Blocked LinuxCNC sources mapped to wasm-safe shim files. |' docs/linuxcnc-wasm-blockers-source-map.md >/dev/null +grep -F 'Python/Boost.Python remap paths remain tracked blockers' docs/linuxcnc-wasm-blockers-source-map.md >/dev/null grep -F 'check-linuxcnc-switchkins-remap-table-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-kinematics-source-files.txt' test-native.sh >/dev/null grep -F 'check-linuxcnc-switchkins-remap-table-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-kinematics-source-files.txt' test-linuxcnc-source-link.sh >/dev/null grep -F 'check-linuxcnc-switchkins-remap-table-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-kinematics-source-files.txt' build-wasm.sh >/dev/null @@ -1997,6 +2001,8 @@ if ! grep -F "missing manifest source: src/emc/rs274ngc/does_not_exist.cc" "$mis exit 1 fi +./check-linuxcnc-wasm-blockers-source-map.sh linuxcnc-rs274-wasm-source-files.txt + if [[ "$guardrails_only" == "1" ]]; then echo "all native guardrail checks passed" exit 0