验证 Boost.Python shim 惰性边界
This commit is contained in:
@@ -1,12 +1,31 @@
|
|||||||
|
#include "boost/python/class.hpp"
|
||||||
|
#include "boost/python/converter/registry.hpp"
|
||||||
|
#include "boost/python/def.hpp"
|
||||||
|
#include "boost/python/dict.hpp"
|
||||||
|
#include "boost/python/enum.hpp"
|
||||||
|
#include "boost/python/exception_translator.hpp"
|
||||||
|
#include "boost/python/extract.hpp"
|
||||||
|
#include "boost/python/import.hpp"
|
||||||
|
#include "boost/python/list.hpp"
|
||||||
|
#include "boost/python/module.hpp"
|
||||||
#include "boost/python/object.hpp"
|
#include "boost/python/object.hpp"
|
||||||
|
#include "boost/python/object/class_detail.hpp"
|
||||||
|
#include "boost/python/return_internal_reference.hpp"
|
||||||
|
#include "boost/python/scope.hpp"
|
||||||
|
#include "boost/python/str.hpp"
|
||||||
|
#include "boost/python/suite/indexing/map_indexing_suite.hpp"
|
||||||
|
#include "boost/python/tuple.hpp"
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
// LinuxCNC source basis: src/emc/rs274ngc/gcodemodule.cc,
|
// LinuxCNC source basis: src/emc/rs274ngc/gcodemodule.cc,
|
||||||
// interpmodule.cc, and py*.cc use these Python C API entry points while
|
// interpmodule.cc, py*.cc, interp_python.cc, interp_namedparams.cc, and
|
||||||
// defining RS274 Python binding objects. The WASM shim keeps the API inert
|
// src/emc/pythonplugin/python_plugin.cc use these Python C API and
|
||||||
// and link-safe while browser Python execution remains disabled.
|
// Boost.Python entry points. The WASM shim keeps the API inert and link-safe
|
||||||
|
// while browser Python execution remains disabled.
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct ProbeObject {
|
struct ProbeObject {
|
||||||
@@ -14,8 +33,111 @@ struct ProbeObject {
|
|||||||
int value;
|
int value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ProbeCppObject {
|
||||||
|
int value = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
PyObject *probe_getter(PyObject *, void *) {
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
int probe_setter(PyObject *, PyObject *, void *) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *probe_method(PyObject *, PyObject *) {
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
void translate_probe_exception(const std::runtime_error &) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool boost_python_shims_are_inert() {
|
||||||
|
namespace bp = boost::python;
|
||||||
|
|
||||||
|
bp::object object;
|
||||||
|
if (object.ptr() != nullptr || object.attr("missing").operator bp::object().ptr() != nullptr ||
|
||||||
|
object["missing"].ptr() != nullptr || object[0].ptr() != nullptr ||
|
||||||
|
object().ptr() != nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bp::list list;
|
||||||
|
list.append(object);
|
||||||
|
list.extend(list);
|
||||||
|
bp::tuple tuple(list);
|
||||||
|
bp::dict dict;
|
||||||
|
if (bp::tuple().ptr() != nullptr || tuple.ptr() != nullptr ||
|
||||||
|
bp::make_tuple(1, 2.0, "three").ptr() != nullptr ||
|
||||||
|
dict.keys().ptr() != nullptr || bp::len(list) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((object % tuple).ptr() != nullptr || ("linuxcnc" % tuple).ptr() != nullptr ||
|
||||||
|
(object + object).ptr() != nullptr || (object + "suffix").ptr() != nullptr ||
|
||||||
|
("prefix" + object).ptr() != nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bp::scope scope(object);
|
||||||
|
scope.attr("this") = object;
|
||||||
|
if (scope.attr("this").operator bp::object().ptr() != nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bp::getattr(object, "__next__").ptr() != nullptr ||
|
||||||
|
bp::make_function(probe_method).ptr() != nullptr ||
|
||||||
|
bp::make_getter(probe_getter).ptr() != nullptr ||
|
||||||
|
bp::make_setter(probe_setter).ptr() != nullptr ||
|
||||||
|
bp::import("traceback").ptr() != nullptr ||
|
||||||
|
bp::str("\n").join(object).ptr() != nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (static_cast<int>(bp::extract<int>(object)) != 0 ||
|
||||||
|
static_cast<double>(bp::extract<double>(object)) != 0.0 ||
|
||||||
|
static_cast<std::string>(bp::extract<std::string>(object)) != std::string() ||
|
||||||
|
static_cast<char *>(bp::extract<char *>(object)) != nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bp::handle<> default_handle;
|
||||||
|
bp::handle<> null_handle(bp::allow_null(static_cast<PyObject *>(nullptr)));
|
||||||
|
bp::handle<> borrowed_handle(bp::borrowed(Py_None));
|
||||||
|
if (default_handle || default_handle.get() != nullptr ||
|
||||||
|
null_handle || null_handle.get() != nullptr ||
|
||||||
|
borrowed_handle || borrowed_handle.get() != nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bp::handle_exception();
|
||||||
|
|
||||||
|
bp::class_<ProbeCppObject>("ProbeCppObject")
|
||||||
|
.def("method", probe_method)
|
||||||
|
.def_readwrite("value", &ProbeCppObject::value)
|
||||||
|
.add_property("property", bp::make_getter(probe_getter), bp::make_setter(probe_setter));
|
||||||
|
bp::class_<ProbeCppObject>("ProbeCppObjectNoInit", bp::no_init);
|
||||||
|
bp::class_<ProbeCppObject>("ProbeCppObjectDoc", "doc");
|
||||||
|
bp::class_<ProbeCppObject>("ProbeCppObjectDocNoInit", "doc", bp::no_init);
|
||||||
|
|
||||||
|
bp::enum_<int>("ProbeEnum").value("one", 1).export_values();
|
||||||
|
bp::def("probe", probe_method);
|
||||||
|
bp::register_exception_translator<std::runtime_error>(translate_probe_exception);
|
||||||
|
bp::return_internal_reference<1, bp::default_call_policies> reference_policy;
|
||||||
|
(void)reference_policy;
|
||||||
|
bp::map_indexing_suite<std::map<int, int>> map_suite;
|
||||||
|
(void)map_suite;
|
||||||
|
if (bp::objects::registered_class_object(bp::type_id<ProbeCppObject>()) != nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
BOOST_PYTHON_MODULE(cnc_sim_python_c_api_probe_module) {
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
if (Py_IsInitialized() != 1) {
|
if (Py_IsInitialized() != 1) {
|
||||||
return 1;
|
return 1;
|
||||||
@@ -123,5 +245,8 @@ int main() {
|
|||||||
if (PyErr_Format(PyExc_TypeError, "linuxcnc") != nullptr) {
|
if (PyErr_Format(PyExc_TypeError, "linuxcnc") != nullptr) {
|
||||||
return 15;
|
return 15;
|
||||||
}
|
}
|
||||||
|
if (!boost_python_shims_are_inert()) {
|
||||||
|
return 28;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user