Link wasm runtime status constructors
This commit is contained in:
@@ -102,7 +102,7 @@ if [[ "$manifest_core_count" -eq 0 || "$manifest_blocked_count" -eq 0 ]]; then
|
||||
echo "unexpected wasm manifest partition: core=$manifest_core_count blocked=$manifest_blocked_count" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$manifest" == "$default_manifest" ]] && [[ "$manifest_core_count" -ne 25 || "$manifest_blocked_count" -ne 9 ]]; then
|
||||
if [[ "$manifest" == "$default_manifest" ]] && [[ "$manifest_core_count" -ne 26 || "$manifest_blocked_count" -ne 9 ]]; then
|
||||
echo "unexpected wasm manifest partition: core=$manifest_core_count blocked=$manifest_blocked_count" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -151,6 +151,8 @@ if(CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE)
|
||||
message(STATUS "LinuxCNC wasm blocked sources: ${linuxcnc_wasm_blocked_source_count}")
|
||||
|
||||
set(cnc_sim_wasm_safe_preinclude_options "SHELL:-include wctype.h")
|
||||
set(cnc_sim_wasm_safe_section_options -ffunction-sections -fdata-sections)
|
||||
set(cnc_sim_wasm_safe_link_options "-Wl,--gc-sections")
|
||||
if(EMSCRIPTEN)
|
||||
list(APPEND cnc_sim_wasm_safe_preinclude_options "SHELL:-include libgen.h")
|
||||
find_path(CNC_SIM_FMT_INCLUDE_DIR fmt/format.h
|
||||
@@ -166,7 +168,9 @@ if(CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/emc_status_shim.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/gettext_shim.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/linuxcnc_runtime_shim.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/nml_status_shim.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/python_c_api_shim.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/rcs_print_shim.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/rtapi_compat.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/tooldata/tooldata_mmap_backend.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/tooldata/tooldata_runtime_stubs.cc
|
||||
@@ -179,7 +183,10 @@ if(CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE)
|
||||
)
|
||||
target_compile_features(linuxcnc_rs274_wasm_safe_probe_objects PUBLIC cxx_std_20)
|
||||
target_compile_definitions(linuxcnc_rs274_wasm_safe_probe_objects PRIVATE ULAPI)
|
||||
target_compile_options(linuxcnc_rs274_wasm_safe_probe_objects PRIVATE ${cnc_sim_wasm_safe_preinclude_options})
|
||||
target_compile_options(linuxcnc_rs274_wasm_safe_probe_objects PRIVATE
|
||||
${cnc_sim_wasm_safe_preinclude_options}
|
||||
${cnc_sim_wasm_safe_section_options}
|
||||
)
|
||||
target_include_directories(linuxcnc_rs274_wasm_safe_probe_objects
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
@@ -306,6 +313,7 @@ if(CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE)
|
||||
ULAPI
|
||||
)
|
||||
target_compile_options(linuxcnc_rs274_wasm_safe_probe PRIVATE ${cnc_sim_wasm_safe_preinclude_options})
|
||||
target_link_options(linuxcnc_rs274_wasm_safe_probe PRIVATE ${cnc_sim_wasm_safe_link_options})
|
||||
target_include_directories(linuxcnc_rs274_wasm_safe_probe
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
@@ -332,6 +340,7 @@ if(CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE)
|
||||
target_compile_features(cnc_sim_wasm_runtime_probe PRIVATE cxx_std_20)
|
||||
target_compile_definitions(cnc_sim_wasm_runtime_probe PRIVATE ULAPI)
|
||||
target_compile_options(cnc_sim_wasm_runtime_probe PRIVATE ${cnc_sim_wasm_safe_preinclude_options})
|
||||
target_link_options(cnc_sim_wasm_runtime_probe PRIVATE ${cnc_sim_wasm_safe_link_options})
|
||||
target_include_directories(cnc_sim_wasm_runtime_probe
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
@@ -492,6 +501,7 @@ if(EMSCRIPTEN)
|
||||
)
|
||||
|
||||
target_link_options(cnc_sim_wasm PRIVATE
|
||||
${cnc_sim_wasm_safe_link_options}
|
||||
"--no-entry"
|
||||
"-sMODULARIZE=1"
|
||||
"-sEXPORT_NAME=createCncSimModule"
|
||||
|
||||
@@ -78,6 +78,8 @@ int main() {
|
||||
const char program[] =
|
||||
"G21 G90 G17\n"
|
||||
"G0 X1\n"
|
||||
"F100\n"
|
||||
"G2 X2 Y0 I0.5 J0\n"
|
||||
"M30\n";
|
||||
if (cnc_sim_parse_program(sim, program, sizeof(program) - 1) != 0) {
|
||||
cnc_sim_destroy(sim);
|
||||
@@ -85,15 +87,20 @@ int main() {
|
||||
}
|
||||
|
||||
bool saw_linuxcnc_rapid = false;
|
||||
bool saw_linuxcnc_arc = false;
|
||||
bool saw_program_end = false;
|
||||
for (const auto &event : events) {
|
||||
saw_linuxcnc_rapid = saw_linuxcnc_rapid ||
|
||||
(event.type == CNC_SIM_EVENT_RAPID &&
|
||||
event.line == 2 &&
|
||||
near(event.end.x, 1.0));
|
||||
saw_linuxcnc_arc = saw_linuxcnc_arc ||
|
||||
(event.type == CNC_SIM_EVENT_ARC_FEED &&
|
||||
event.line == 4 &&
|
||||
near(event.end.x, 2.0));
|
||||
saw_program_end = saw_program_end || event.type == CNC_SIM_EVENT_PROGRAM_END;
|
||||
}
|
||||
|
||||
cnc_sim_destroy(sim);
|
||||
return saw_linuxcnc_rapid && saw_program_end ? 0 : 4;
|
||||
return saw_linuxcnc_rapid && saw_linuxcnc_arc && saw_program_end ? 0 : 4;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "nml_intf/emc_nml.hh"
|
||||
|
||||
EMC_STAT *emcStatus = nullptr;
|
||||
|
||||
// LinuxCNC src/emc/sai/dummyemcstat.cc uses the same source-backed status
|
||||
// object when the interpreter runs without the task controller.
|
||||
EMC_STAT *emcStatus = new EMC_STAT;
|
||||
|
||||
71
core/wasm_shims/nml_status_shim.cc
Normal file
71
core/wasm_shims/nml_status_shim.cc
Normal file
@@ -0,0 +1,71 @@
|
||||
#include "libnml/nml/nmlmsg.hh"
|
||||
#include "libnml/nml/stat_msg.hh"
|
||||
#include "libnml/rcs/rcs_print.hh"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
int NMLmsg::automatically_clear = 1;
|
||||
|
||||
NMLmsg::NMLmsg(NMLTYPE t, long s) {
|
||||
_type = t;
|
||||
size = s;
|
||||
if (automatically_clear) {
|
||||
clear();
|
||||
}
|
||||
if (size < static_cast<long>(sizeof(NMLmsg))) {
|
||||
rcs_print_error("NMLmsg: size(=%ld) must be atleast %zu\n", size, sizeof(NMLmsg));
|
||||
size = sizeof(NMLmsg);
|
||||
}
|
||||
if (_type <= 0) {
|
||||
rcs_print_error("NMLmsg: type(=%d) should be greater than zero.\n", static_cast<int>(_type));
|
||||
}
|
||||
}
|
||||
|
||||
NMLmsg::NMLmsg(NMLTYPE t, size_t s) {
|
||||
_type = t;
|
||||
size = static_cast<long>(s);
|
||||
if (automatically_clear) {
|
||||
clear();
|
||||
}
|
||||
if (size < static_cast<long>(sizeof(NMLmsg))) {
|
||||
rcs_print_error("NMLmsg: size(=%ld) must be atleast %zu\n", size, sizeof(NMLmsg));
|
||||
size = sizeof(NMLmsg);
|
||||
}
|
||||
if (_type <= 0) {
|
||||
rcs_print_error("NMLmsg: type(=%d) should be greater than zero.\n", static_cast<int>(_type));
|
||||
}
|
||||
}
|
||||
|
||||
NMLmsg::NMLmsg(NMLTYPE t, long s, int noclear) {
|
||||
if (automatically_clear && !noclear) {
|
||||
clear();
|
||||
}
|
||||
_type = t;
|
||||
size = s;
|
||||
if (size < static_cast<long>(sizeof(NMLmsg))) {
|
||||
rcs_print_error("NMLmsg: size(=%ld) must be atleast %zu\n", size, sizeof(NMLmsg));
|
||||
size = sizeof(NMLmsg);
|
||||
}
|
||||
if (_type <= 0) {
|
||||
rcs_print_error("NMLmsg: type(=%d) should be greater than zero.\n", static_cast<int>(_type));
|
||||
}
|
||||
}
|
||||
|
||||
void NMLmsg::clear() {
|
||||
const long temp_size = size;
|
||||
const NMLTYPE temp_type = _type;
|
||||
std::memset(static_cast<void *>(this), 0, static_cast<size_t>(size));
|
||||
size = temp_size;
|
||||
_type = temp_type;
|
||||
if (size < static_cast<long>(sizeof(NMLmsg))) {
|
||||
rcs_print_error("NMLmsg: size(=%ld) must be atleast %zu\n", size, sizeof(NMLmsg));
|
||||
size = sizeof(NMLmsg);
|
||||
}
|
||||
}
|
||||
|
||||
RCS_STAT_MSG::RCS_STAT_MSG(NMLTYPE t, size_t sz) : NMLmsg(t, sz) {
|
||||
command_type = -1;
|
||||
echo_serial_number = -1;
|
||||
status = RCS_STATUS::UNINITIALIZED;
|
||||
_state = -1;
|
||||
}
|
||||
14
core/wasm_shims/rcs_print_shim.cc
Normal file
14
core/wasm_shims/rcs_print_shim.cc
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
|
||||
extern "C" int set_print_rcs_error_info(const char *, int) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int print_rcs_error_new(const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
const int rc = std::vfprintf(stderr, format, args);
|
||||
va_end(args);
|
||||
return rc;
|
||||
}
|
||||
@@ -69,6 +69,15 @@ These are not needed for the browser simulator ABI and should not be part of the
|
||||
- persistent parameter file writes.
|
||||
- dynamic INI/HAL queries.
|
||||
|
||||
The wasm-safe runtime now constructs its detached `EMC_STAT` through LinuxCNC
|
||||
`src/emc/nml_intf/emcops.cc`. The singleton follows LinuxCNC
|
||||
`src/emc/sai/dummyemcstat.cc`, and the required `NMLmsg`/`RCS_STAT_MSG`
|
||||
constructors are trimmed from `src/libnml/nml/nmlmsg.cc` and
|
||||
`src/libnml/nml/stat_msg.cc` in `core/wasm_shims/nml_status_shim.cc`, so
|
||||
interpreter paths such as `Interp::tag_arc()` in `interp_convert.cc` read
|
||||
initialized LinuxCNC status defaults without linking the task controller or
|
||||
native NML channels.
|
||||
|
||||
## Current syntax probe
|
||||
|
||||
Run:
|
||||
|
||||
@@ -290,7 +290,7 @@ Build and source-link guardrails:
|
||||
Node or browser smoke tests.
|
||||
- `build-wasm.sh` must run `test-web-wasm-node-smoke.sh` before the browser
|
||||
smoke so the Node prerequisite, syntax, and minimum-step checks are enforced.
|
||||
- The default wasm manifest partition must remain explicitly checked for 25
|
||||
- The default wasm manifest partition must remain explicitly checked for 26
|
||||
wasm-safe core sources and 9 blocked sources.
|
||||
- Manifest source listers must reject malformed lines, absolute source paths,
|
||||
unknown groups, unknown filters, and duplicate source entries.
|
||||
|
||||
@@ -25,6 +25,7 @@ core:src/emc/rs274ngc/interp_remap.cc:Python remap support satisfied by wasm Pyt
|
||||
core:src/emc/rs274ngc/rs274ngc_pre.cc:Interp implementation covered by rs274ngc_pre link probe
|
||||
core:src/emc/tooldata/tooldata_common.cc:shared tool table parser/format logic linked with wasm-safe mmap backend
|
||||
core:src/emc/ini/inifile.cc:INI reader needed by rs274ngc_pre source-link probe
|
||||
core:src/emc/nml_intf/emcops.cc:EMC status constructors needed by source-backed browser status singleton
|
||||
blocked:src/emc/tooldata/tooldata_mmap.cc:native mmap implementation
|
||||
blocked:src/emc/rs274ngc/canonmodule.cc:Python module binding, tracked for full rs274ngc source coverage
|
||||
blocked:src/emc/rs274ngc/gcodemodule.cc:Python gcode module binding, tracked for full rs274ngc source coverage
|
||||
@@ -52,3 +53,5 @@ header:src/emc/rs274ngc/rs274ngc_return.hh:LinuxCNC rs274 return code header
|
||||
header:src/emc/rs274ngc/units.h:LinuxCNC rs274 units helper header
|
||||
metadata:src/emc/rs274ngc/Submakefile:LinuxCNC rs274 make build metadata tracked for full directory coverage
|
||||
metadata:src/emc/rs274ngc/meson.build:LinuxCNC rs274 meson build metadata tracked for full directory coverage
|
||||
metadata:src/libnml/nml/stat_msg.cc:source basis for wasm-safe RCS_STAT_MSG constructor shim
|
||||
metadata:src/libnml/nml/nmlmsg.cc:source basis for wasm-safe NMLmsg constructor shim
|
||||
|
||||
@@ -526,7 +526,7 @@ grep -F 'must copy `build/wasm/cnc_sim.js` and' docs/linuxcnc-source-policy.md >
|
||||
grep -F 'must compare copied artifacts with `cmp -s` before running' docs/linuxcnc-source-policy.md >/dev/null
|
||||
grep -F 'must run `test-web-wasm-node-smoke.sh` before the browser' docs/linuxcnc-source-policy.md >/dev/null
|
||||
grep -F 'test-web-wasm-node-smoke.sh' docs/linuxcnc-porting.md >/dev/null
|
||||
grep -F 'explicitly checked for 25' docs/linuxcnc-source-policy.md >/dev/null
|
||||
grep -F 'explicitly checked for 26' docs/linuxcnc-source-policy.md >/dev/null
|
||||
grep -F 'wasm-safe core sources and 9 blocked sources' docs/linuxcnc-source-policy.md >/dev/null
|
||||
grep -F 'must reject malformed lines, absolute source paths,' docs/linuxcnc-source-policy.md >/dev/null
|
||||
grep -F 'must include the built LinuxCNC `lib` path and rpath' docs/linuxcnc-source-policy.md >/dev/null
|
||||
|
||||
@@ -169,7 +169,7 @@ else
|
||||
fi
|
||||
|
||||
grep -F "[manifest]" <<<"$output" >/dev/null
|
||||
grep -F "core=25" <<<"$(sed -n '/^\[manifest\]/,/^$/p' <<<"$output")" >/dev/null
|
||||
grep -F "core=26" <<<"$(sed -n '/^\[manifest\]/,/^$/p' <<<"$output")" >/dev/null
|
||||
grep -F "blocked=9" <<<"$(sed -n '/^\[manifest\]/,/^$/p' <<<"$output")" >/dev/null
|
||||
grep -F "[python]" <<<"$output" >/dev/null
|
||||
grep -F "src/emc/rs274ngc/canonmodule.cc" <<<"$(sed -n '/^\[python\]/,/^$/p' <<<"$output")" >/dev/null
|
||||
|
||||
@@ -853,7 +853,7 @@ if grep -F 'grep -c . <<<"$manifest_core_output" || true' build-wasm.sh >/dev/nu
|
||||
echo "build-wasm still counts manifest output through grep -c with || true" >&2
|
||||
exit 1
|
||||
fi
|
||||
grep -F -- 'if [[ "$manifest" == "$default_manifest" ]] && [[ "$manifest_core_count" -ne 25 || "$manifest_blocked_count" -ne 9 ]]; then' build-wasm.sh >/dev/null
|
||||
grep -F -- 'if [[ "$manifest" == "$default_manifest" ]] && [[ "$manifest_core_count" -ne 26 || "$manifest_blocked_count" -ne 9 ]]; then' build-wasm.sh >/dev/null
|
||||
grep -F 'LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" "$manifest"' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null
|
||||
./list-linuxcnc-wasm-safe-shims.sh >/dev/null
|
||||
./list-linuxcnc-wasm-safe-project-sources.sh >/dev/null
|
||||
@@ -1320,7 +1320,7 @@ required_shim_sources="$build_dir/wasm_safe_shim_sources.txt"
|
||||
required_project_sources="$build_dir/wasm_safe_project_sources.txt"
|
||||
./list-linuxcnc-wasm-safe-project-sources.sh > "$required_project_sources"
|
||||
|
||||
if [[ "$manifest" == "$default_manifest" ]] && [[ "$manifest_core_count" -ne 25 || "$manifest_blocked_count" -ne 9 ]]; then
|
||||
if [[ "$manifest" == "$default_manifest" ]] && [[ "$manifest_core_count" -ne 26 || "$manifest_blocked_count" -ne 9 ]]; then
|
||||
echo "unexpected wasm manifest partition: core=$manifest_core_count blocked=$manifest_blocked_count" >&2
|
||||
exit 1
|
||||
fi
|
||||
@@ -1394,7 +1394,12 @@ grep -F 'NO_CMAKE_FIND_ROOT_PATH' core/CMakeLists.txt >/dev/null
|
||||
grep -F 'list(APPEND cnc_sim_wasm_safe_preinclude_options "SHELL:-idirafter ${CNC_SIM_FMT_INCLUDE_DIR}")' core/CMakeLists.txt >/dev/null
|
||||
grep -F 'FMT_HEADER_ONLY=1' core/CMakeLists.txt >/dev/null
|
||||
grep -F '${CNC_SIM_FMT_INCLUDE_DIR}' core/CMakeLists.txt >/dev/null
|
||||
grep -F 'target_compile_options(linuxcnc_rs274_wasm_safe_probe_objects PRIVATE ${cnc_sim_wasm_safe_preinclude_options})' core/CMakeLists.txt >/dev/null
|
||||
grep -F 'target_compile_options(linuxcnc_rs274_wasm_safe_probe_objects PRIVATE' core/CMakeLists.txt >/dev/null
|
||||
grep -F '${cnc_sim_wasm_safe_preinclude_options}' core/CMakeLists.txt >/dev/null
|
||||
grep -F 'set(cnc_sim_wasm_safe_section_options -ffunction-sections -fdata-sections)' core/CMakeLists.txt >/dev/null
|
||||
grep -F 'set(cnc_sim_wasm_safe_link_options "-Wl,--gc-sections")' core/CMakeLists.txt >/dev/null
|
||||
grep -F 'target_link_options(linuxcnc_rs274_wasm_safe_probe PRIVATE ${cnc_sim_wasm_safe_link_options})' core/CMakeLists.txt >/dev/null
|
||||
grep -F 'target_link_options(cnc_sim_wasm_runtime_probe PRIVATE ${cnc_sim_wasm_safe_link_options})' core/CMakeLists.txt >/dev/null
|
||||
grep -F 'target_compile_options(linuxcnc_rs274_wasm_safe_probe PRIVATE ${cnc_sim_wasm_safe_preinclude_options})' core/CMakeLists.txt >/dev/null
|
||||
grep -F 'target_compile_options(cnc_sim_objects PRIVATE ${cnc_sim_wasm_safe_preinclude_options})' core/CMakeLists.txt >/dev/null
|
||||
grep -F 'target_compile_options(cnc_sim_wasm_runtime_probe PRIVATE ${cnc_sim_wasm_safe_preinclude_options})' core/CMakeLists.txt >/dev/null
|
||||
@@ -1406,6 +1411,9 @@ grep -F 'inline char *basename(const char *path)' core/wasm_shims/libgen.h >/dev
|
||||
grep -F 'return basename(const_cast<char *>(path));' core/wasm_shims/libgen.h >/dev/null
|
||||
grep -F 'extern "C" int wordexp(const char *words, wordexp_t *pwordexp, int)' core/wasm_shims/linuxcnc_runtime_shim.cc >/dev/null
|
||||
grep -F 'extern "C" void wordfree(wordexp_t *pwordexp)' core/wasm_shims/linuxcnc_runtime_shim.cc >/dev/null
|
||||
grep -F 'EMC_STAT *emcStatus = new EMC_STAT;' core/wasm_shims/emc_status_shim.cc >/dev/null
|
||||
grep -F 'wasm_shims/nml_status_shim.cc' core/CMakeLists.txt >/dev/null
|
||||
grep -F 'wasm_shims/rcs_print_shim.cc' core/CMakeLists.txt >/dev/null
|
||||
grep -F '$<TARGET_OBJECTS:linuxcnc_rs274_wasm_safe_probe_objects>' core/CMakeLists.txt >/dev/null
|
||||
grep -F '$<TARGET_OBJECTS:cnc_sim_objects>' core/CMakeLists.txt >/dev/null
|
||||
grep -F 'CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND' core/CMakeLists.txt >/dev/null
|
||||
|
||||
@@ -27,6 +27,8 @@ grep -F "parse_linuxcnc_rs274_backend" "$symbol_file" >/dev/null
|
||||
grep -F "parse_gcode_with_backend" "$symbol_file" >/dev/null
|
||||
grep -F "Interp::read(char const*)" "$symbol_file" >/dev/null
|
||||
grep -F "Interp::init()" "$symbol_file" >/dev/null
|
||||
grep -F "EMC_STAT::EMC_STAT()" "$symbol_file" >/dev/null
|
||||
grep -E '(^| )emcStatus$' "$symbol_file" >/dev/null
|
||||
grep -E '(^| )wordexp($| )' "$symbol_file" >/dev/null
|
||||
grep -E '(^| )wordfree($| )' "$symbol_file" >/dev/null
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user