按规划继续工作
结论:解释器 WASM、SDK 统一入口、浏览器解释器 smoke 与兼容性文档已闭环,native 和 host/WASM/browser 验证全部通过。
This commit is contained in:
41
wasm-port/runtime/sdk/README.md
Normal file
41
wasm-port/runtime/sdk/README.md
Normal 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)`
|
||||
2
wasm-port/runtime/sdk/src/index.js
Normal file
2
wasm-port/runtime/sdk/src/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
export { createLinuxCncIniSdk } from "./linuxcnc-ini.js";
|
||||
export { createLinuxCncInterpSdk } from "./linuxcnc-interp.js";
|
||||
73
wasm-port/runtime/sdk/src/linuxcnc-interp.js
Normal file
73
wasm-port/runtime/sdk/src/linuxcnc-interp.js
Normal 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);
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user