执行 AGENTS align-linuxcnc 加速规则
结论:补强 WASM Python C API 可执行探针,依据 LinuxCNC src/emc/rs274ngc/gcodemodule.cc、interpmodule.cc 和 py*.cc 对 PyObject_New、Py_TYPE、Py_None、PyList_Type 等 Python C API 的绑定用法。验证通过:./test-linuxcnc-wasm-python-c-api-symbols.sh、./test-native.sh、./test-linuxcnc-source-link.sh。
This commit is contained in:
73
core/wasm_shims/python_c_api_probe_main.cc
Normal file
73
core/wasm_shims/python_c_api_probe_main.cc
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#include "boost/python/object.hpp"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
// LinuxCNC source basis: src/emc/rs274ngc/gcodemodule.cc,
|
||||||
|
// interpmodule.cc, and py*.cc use these Python C API entry points while
|
||||||
|
// defining RS274 Python binding objects. The WASM shim keeps the API inert
|
||||||
|
// and link-safe while browser Python execution remains disabled.
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct ProbeObject {
|
||||||
|
PyObject_HEAD
|
||||||
|
int value;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
if (Py_IsInitialized() != 1) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (PyErr_Occurred() != nullptr) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
PyObject *exc = reinterpret_cast<PyObject *>(1);
|
||||||
|
PyObject *val = reinterpret_cast<PyObject *>(1);
|
||||||
|
PyObject *tb = reinterpret_cast<PyObject *>(1);
|
||||||
|
PyErr_Fetch(&exc, &val, &tb);
|
||||||
|
if (exc || val || tb) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
if (!Py_None || !Py_TYPE(Py_None) || std::strcmp(Py_TYPE(Py_None)->tp_name, "NoneType") != 0) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
if (PyUnicode_FromString("linuxcnc") != Py_None) {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
if (std::strcmp(PyUnicode_AsUTF8(Py_None), "") != 0) {
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
if (PyLong_FromLong(7) != Py_None || PyLong_AsLong(Py_None) != 0) {
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
if (PyFloat_AsDouble(Py_None) != 0.0) {
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
if (PyTuple_New(2) != Py_None || PyTuple_SetItem(Py_None, 0, Py_None) != 0 || PyTuple_Size(Py_None) != 0) {
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
if (PyList_New(2) != Py_None || PyList_SetItem(Py_None, 0, Py_None) != 0 || PyList_Size(Py_None) != 0) {
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
if (PyObject_IsTrue(Py_None) != 0 || PyCallable_Check(Py_None) != 0 || PyObject_IsInstance(Py_None, Py_None) != 0) {
|
||||||
|
return 11;
|
||||||
|
}
|
||||||
|
ProbeObject *probe = PyObject_New(ProbeObject, &PyList_Type);
|
||||||
|
if (!probe || Py_TYPE(reinterpret_cast<PyObject *>(probe)) != &PyList_Type) {
|
||||||
|
std::free(probe);
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
std::free(probe);
|
||||||
|
if (PyModule_Create(nullptr) != Py_None || PyModule_AddObject(Py_None, "value", Py_None) != 0) {
|
||||||
|
return 13;
|
||||||
|
}
|
||||||
|
if (PyType_Ready(&PyList_Type) != 0 || PyType_GenericNew(&PyList_Type, Py_None, Py_None) != Py_None) {
|
||||||
|
return 14;
|
||||||
|
}
|
||||||
|
if (PyErr_Format(PyExc_TypeError, "linuxcnc") != nullptr) {
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -70,6 +70,12 @@ object_sources=(
|
|||||||
"$python_c_api_shim"
|
"$python_c_api_shim"
|
||||||
"$runtime_shim"
|
"$runtime_shim"
|
||||||
)
|
)
|
||||||
|
probe_objects=(
|
||||||
|
"$build_dir/python_c_api_probe_main.o"
|
||||||
|
)
|
||||||
|
probe_sources=(
|
||||||
|
core/wasm_shims/python_c_api_probe_main.cc
|
||||||
|
)
|
||||||
for source in "${python_binding_sources[@]}"; do
|
for source in "${python_binding_sources[@]}"; do
|
||||||
object_name=$(basename "$source" .cc)
|
object_name=$(basename "$source" .cc)
|
||||||
objects+=("$build_dir/$object_name.o")
|
objects+=("$build_dir/$object_name.o")
|
||||||
@@ -88,9 +94,11 @@ next_signature="$build_dir/python-c-api.signature.next"
|
|||||||
printf '\n'
|
printf '\n'
|
||||||
printf 'SOURCES:\n'
|
printf 'SOURCES:\n'
|
||||||
printf '%s\n' "${object_sources[@]}"
|
printf '%s\n' "${object_sources[@]}"
|
||||||
|
printf 'PROBE_SOURCES:\n'
|
||||||
|
printf '%s\n' "${probe_sources[@]}"
|
||||||
} > "$next_signature"
|
} > "$next_signature"
|
||||||
if [[ ! -f "$signature" ]] || ! cmp -s "$signature" "$next_signature"; then
|
if [[ ! -f "$signature" ]] || ! cmp -s "$signature" "$next_signature"; then
|
||||||
rm -f "$build_dir"/*.o "$build_dir"/*.d
|
rm -f "$build_dir"/*.o "$build_dir"/*.d "$build_dir/python_c_api_probe"
|
||||||
fi
|
fi
|
||||||
mv "$next_signature" "$signature"
|
mv "$next_signature" "$signature"
|
||||||
|
|
||||||
@@ -107,8 +115,11 @@ makefile="$build_dir/python-c-api.mk"
|
|||||||
for object in "${objects[@]}"; do
|
for object in "${objects[@]}"; do
|
||||||
printf 'DEP_FILES += %s.d\n' "$object"
|
printf 'DEP_FILES += %s.d\n' "$object"
|
||||||
done
|
done
|
||||||
|
for object in "${probe_objects[@]}"; do
|
||||||
|
printf 'DEP_FILES += %s.d\n' "$object"
|
||||||
|
done
|
||||||
printf '\n.PHONY: all\n'
|
printf '\n.PHONY: all\n'
|
||||||
printf 'all: $(OBJECTS)\n\n'
|
printf 'all: $(OBJECTS) %s\n\n' "$build_dir/python_c_api_probe"
|
||||||
|
|
||||||
object_index=0
|
object_index=0
|
||||||
for source in "${object_sources[@]}"; do
|
for source in "${object_sources[@]}"; do
|
||||||
@@ -116,6 +127,14 @@ makefile="$build_dir/python-c-api.mk"
|
|||||||
printf '\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s.d -c %s -o %s\n\n' "${objects[$object_index]}" "$source" "${objects[$object_index]}"
|
printf '\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s.d -c %s -o %s\n\n' "${objects[$object_index]}" "$source" "${objects[$object_index]}"
|
||||||
object_index=$((object_index + 1))
|
object_index=$((object_index + 1))
|
||||||
done
|
done
|
||||||
|
probe_index=0
|
||||||
|
for source in "${probe_sources[@]}"; do
|
||||||
|
printf '%s: %s\n' "${probe_objects[$probe_index]}" "$source"
|
||||||
|
printf '\t@$(CXX) $(COMMON_FLAGS) -MMD -MP -MF %s.d -c %s -o %s\n\n' "${probe_objects[$probe_index]}" "$source" "${probe_objects[$probe_index]}"
|
||||||
|
probe_index=$((probe_index + 1))
|
||||||
|
done
|
||||||
|
printf '%s: %s %s\n' "$build_dir/python_c_api_probe" "$build_dir/python_c_api_shim.o" "${probe_objects[*]}"
|
||||||
|
printf '\t@$(CXX) %s %s -o %s\n\n' "$build_dir/python_c_api_shim.o" "${probe_objects[*]}" "$build_dir/python_c_api_probe"
|
||||||
printf '\n-include $(DEP_FILES)\n'
|
printf '\n-include $(DEP_FILES)\n'
|
||||||
} > "$makefile"
|
} > "$makefile"
|
||||||
make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null
|
make --output-sync=target -j"$build_jobs" -f "$makefile" >/dev/null
|
||||||
@@ -229,4 +248,6 @@ if [[ -s "$build_dir/object.missing-python" ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
"$build_dir/python_c_api_probe"
|
||||||
|
|
||||||
echo "linuxcnc wasm Python C API symbol probe passed"
|
echo "linuxcnc wasm Python C API symbol probe passed"
|
||||||
|
|||||||
Reference in New Issue
Block a user