diff --git a/wasm-port/AGENTS.md b/wasm-port/AGENTS.md index a731254..e124eb3 100644 --- a/wasm-port/AGENTS.md +++ b/wasm-port/AGENTS.md @@ -70,7 +70,12 @@ expanded into a separate implementation of G-code behavior. - GUI. 7. Frontend code must be implemented with web technology, not migrated from native GUI code. -8. All build scripts must be incremental. Native and WASM builds must reuse +8. Frontend, browser tests, and Node WASM tests should call generated WASM + modules through `runtime/sdk/src/index.js`. SDK code is a host-boundary + layer only: it may load modules, manage strings, write Emscripten files, + and call exported C ABI functions, but it must not implement G-code, + canonical motion, tool, parameter, kinematics, or planner semantics. +9. All build scripts must be incremental. Native and WASM builds must reuse object files, dependency files, and command fingerprints, and must not unconditionally recompile unchanged source files. diff --git a/wasm-port/README.md b/wasm-port/README.md index 69f3976..781237f 100644 --- a/wasm-port/README.md +++ b/wasm-port/README.md @@ -9,6 +9,9 @@ Rules: 3. Port-specific code, build scripts, adapters, tests, and documentation live here. 4. LinuxCNC source is consumed by reference, copy, generated snapshot, or scripted extraction. 5. The browser/WASM product is managed as a separate program. +6. Browser UI and tests should call WASM modules through `runtime/sdk/src/index.js`. + The SDK is a thin module-loading, string-allocation, Emscripten-FS, and C + ABI wrapper; it must not implement CNC semantics. Suggested layout: @@ -119,6 +122,9 @@ Directory intent: - `vendor/linuxcnc/`: read-only copied LinuxCNC source selected for the port. - `runtime/core/`: the standalone simulation engine built around vendored LinuxCNC code. - `runtime/sdk/`: JavaScript/TypeScript API for calling the WASM engine. + Stable imports should come from `runtime/sdk/src/index.js`. SDK code may + adapt host/runtime edges, but G-code, tool, parameter, kinematics, and + planner behavior must remain in vendored LinuxCNC source. - `runtime/ui/`: HTML + JavaScript CNC simulation frontend. - `runtime/opfs/`: OPFS-backed persistence layer. - `tests/fixtures/`: stable simulation inputs shared by native and browser tests. diff --git a/wasm-port/docs/compatibility-validation.md b/wasm-port/docs/compatibility-validation.md index fb1c62a..245e481 100644 --- a/wasm-port/docs/compatibility-validation.md +++ b/wasm-port/docs/compatibility-validation.md @@ -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 diff --git a/wasm-port/docs/drift-report.md b/wasm-port/docs/drift-report.md index cfa22fd..62ee433 100644 --- a/wasm-port/docs/drift-report.md +++ b/wasm-port/docs/drift-report.md @@ -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 diff --git a/wasm-port/docs/porting-steps-standalone.md b/wasm-port/docs/porting-steps-standalone.md index 1261aad..4ddf733 100644 --- a/wasm-port/docs/porting-steps-standalone.md +++ b/wasm-port/docs/porting-steps-standalone.md @@ -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`. diff --git a/wasm-port/docs/source-reuse-map.md b/wasm-port/docs/source-reuse-map.md index 5fe2b80..b6c708a 100644 --- a/wasm-port/docs/source-reuse-map.md +++ b/wasm-port/docs/source-reuse-map.md @@ -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, diff --git a/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_wasm.cpp b/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_wasm.cpp index 14bf9ae..5406cda 100644 --- a/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_wasm.cpp +++ b/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_wasm.cpp @@ -183,9 +183,13 @@ char *lcinterp_run_program(const char *program_text) } EMSCRIPTEN_KEEPALIVE -char *lcinterp_run_file(const char *path) +char *lcinterp_run_file_with_ini(const char *path, const char *ini_path) { - unsetenv("INI_FILE_NAME"); + if (ini_path && ini_path[0] != '\0') { + setenv("INI_FILE_NAME", ini_path, 1); + } else { + unsetenv("INI_FILE_NAME"); + } Interp interp; standalone::reset_canon_events(); @@ -248,6 +252,12 @@ char *lcinterp_run_file(const char *path) return copy_result(output.str()); } +EMSCRIPTEN_KEEPALIVE +char *lcinterp_run_file(const char *path) +{ + return lcinterp_run_file_with_ini(path, nullptr); +} + EMSCRIPTEN_KEEPALIVE void lcinterp_free_string(char *value) { diff --git a/wasm-port/runtime/sdk/README.md b/wasm-port/runtime/sdk/README.md new file mode 100644 index 0000000..b0fac3d --- /dev/null +++ b/wasm-port/runtime/sdk/README.md @@ -0,0 +1,41 @@ +# LinuxCNC WASM SDK + +This SDK exposes browser/Node JavaScript wrappers for standalone WASM modules +built from vendored LinuxCNC source. + +## Boundary + +The SDK is a host-boundary layer only. It may: + +- load generated Emscripten modules; +- allocate and free C strings; +- write text files into the Emscripten filesystem; +- call exported C ABI functions; +- return LinuxCNC-produced text output to JavaScript callers. + +The SDK must not implement G-code interpretation, canonical motion behavior, +tool semantics, parameter semantics, kinematics, or planner behavior. Those +behaviors must continue to come from vendored LinuxCNC source through the C ABI. + +## Entrypoints + +Use `src/index.js` for stable imports: + +```js +import { + createLinuxCncIniSdk, + createLinuxCncInterpSdk, +} from "./src/index.js"; +``` + +`createLinuxCncIniSdk()` wraps the INI parser module built from vendored +LinuxCNC `inifile.cc`. + +`createLinuxCncInterpSdk()` wraps the interpreter-core module built from +vendored LinuxCNC RS274NGC sources and exposes: + +- `runProgram(programText)` +- `runProgramWithIni(programText, iniPath)` +- `runFile(path)` +- `runFileWithIni(path, iniPath)` +- `writeTextFile(path, text)` diff --git a/wasm-port/runtime/sdk/src/index.js b/wasm-port/runtime/sdk/src/index.js new file mode 100644 index 0000000..1959a46 --- /dev/null +++ b/wasm-port/runtime/sdk/src/index.js @@ -0,0 +1,2 @@ +export { createLinuxCncIniSdk } from "./linuxcnc-ini.js"; +export { createLinuxCncInterpSdk } from "./linuxcnc-interp.js"; diff --git a/wasm-port/runtime/sdk/src/linuxcnc-interp.js b/wasm-port/runtime/sdk/src/linuxcnc-interp.js new file mode 100644 index 0000000..b691690 --- /dev/null +++ b/wasm-port/runtime/sdk/src/linuxcnc-interp.js @@ -0,0 +1,73 @@ +import createLinuxCncInterpModule from "../../../build/wasm/core/linuxcnc_interp.js"; + +function allocCString(mod, value) { + const bytes = mod.lengthBytesUTF8(value) + 1; + const ptr = mod._malloc(bytes); + mod.stringToUTF8(value, ptr, bytes); + return ptr; +} + +function ensureParentPath(mod, path) { + const parts = path.split("/").filter(Boolean); + let current = ""; + for (const part of parts.slice(0, -1)) { + current += `/${part}`; + try { + mod.FS.mkdir(current); + } catch { + // Directory already exists. + } + } +} + +function copyResultString(mod, resultPtr, functionName) { + if (!resultPtr) { + throw new Error(`${functionName} returned null`); + } + return mod.UTF8ToString(resultPtr); +} + +function callStringResult(mod, functionName, ...values) { + const ptrs = values.map((value) => allocCString(mod, value)); + let resultPtr = 0; + try { + resultPtr = mod[`_${functionName}`](...ptrs); + return copyResultString(mod, resultPtr, functionName); + } finally { + if (resultPtr) { + mod._lcinterp_free_string(resultPtr); + } + for (const ptr of ptrs) { + mod._free(ptr); + } + } +} + +export async function createLinuxCncInterpSdk(moduleOptions = {}) { + const mod = await createLinuxCncInterpModule(moduleOptions); + + return { + module: mod, + + writeTextFile(path, text) { + ensureParentPath(mod, path); + mod.FS.writeFile(path, text, { encoding: "utf8" }); + }, + + runProgram(programText) { + return callStringResult(mod, "lcinterp_run_program", programText); + }, + + runProgramWithIni(programText, iniPath) { + return callStringResult(mod, "lcinterp_run_program_with_ini", programText, iniPath); + }, + + runFile(path) { + return callStringResult(mod, "lcinterp_run_file", path); + }, + + runFileWithIni(path, iniPath) { + return callStringResult(mod, "lcinterp_run_file_with_ini", path, iniPath); + }, + }; +} diff --git a/wasm-port/runtime/ui/ini-panel/app.js b/wasm-port/runtime/ui/ini-panel/app.js index 3675b8e..695654b 100644 --- a/wasm-port/runtime/ui/ini-panel/app.js +++ b/wasm-port/runtime/ui/ini-panel/app.js @@ -1,4 +1,4 @@ -import { createLinuxCncIniSdk } from "../../sdk/src/linuxcnc-ini.js"; +import { createLinuxCncIniSdk } from "../../sdk/src/index.js"; import { getOpfsRoot, loadTextFile, diff --git a/wasm-port/tests/browser/ini_panel_smoke.html b/wasm-port/tests/browser/ini_panel_smoke.html index 26c4d9b..f490c21 100644 --- a/wasm-port/tests/browser/ini_panel_smoke.html +++ b/wasm-port/tests/browser/ini_panel_smoke.html @@ -7,7 +7,7 @@
running+ +