按规划继续工作

结论:解释器 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

@@ -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)
{

View File

@@ -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)`

View File

@@ -0,0 +1,2 @@
export { createLinuxCncIniSdk } from "./linuxcnc-ini.js";
export { createLinuxCncInterpSdk } from "./linuxcnc-interp.js";

View File

@@ -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);
},
};
}

View File

@@ -1,4 +1,4 @@
import { createLinuxCncIniSdk } from "../../sdk/src/linuxcnc-ini.js";
import { createLinuxCncIniSdk } from "../../sdk/src/index.js";
import {
getOpfsRoot,
loadTextFile,