26#include "RNA_prototypes.hh"
37#define USE_RNA_AS_PYOBJECT
39#define USE_BYTECODE_WHITELIST
41#ifdef USE_BYTECODE_WHITELIST
45#if PY_VERSION_HEX >= 0x030d0000
49# include <internal/pycore_code.h>
54#ifdef USE_BYTECODE_WHITELIST
75 PyDict_SetItemString(d,
"__builtins__", PyEval_GetBuiltins());
77 mod = PyImport_ImportModule(
"math");
79 PyDict_Merge(d, PyModule_GetDict(
mod), 0);
82#ifdef USE_BYTECODE_WHITELIST
83 PyObject *mod_math =
mod;
87 mod = PyImport_ImportModuleLevel(
"bpy",
nullptr,
nullptr,
nullptr, 0);
94 mod = PyImport_ImportModuleLevel(
"mathutils",
nullptr,
nullptr,
nullptr, 0);
96 PyObject *modsub = PyDict_GetItemString(PyModule_GetDict(
mod),
"noise");
102 mod = PyImport_ImportModuleLevel(
"bl_math",
nullptr,
nullptr,
nullptr, 0);
104 static const char *names[] = {
"clamp",
"lerp",
"smoothstep",
nullptr};
106 for (
const char **pname = names; *pname; ++pname) {
107 PyObject *func = PyDict_GetItemString(PyModule_GetDict(
mod), *pname);
114#ifdef USE_BYTECODE_WHITELIST
118 const char *whitelist[] = {
141 for (
int i = 0; whitelist[
i];
i++) {
146 if (mod_math !=
nullptr) {
147 PyObject *mod_math_dict = PyModule_GetDict(mod_math);
148 PyObject *arg_key, *arg_value;
149 Py_ssize_t arg_pos = 0;
150 while (PyDict_Next(mod_math_dict, &arg_pos, &arg_key, &arg_value)) {
151 const char *
arg_str = PyUnicode_AsUTF8(arg_key);
179 PyObject *item = PyFloat_FromDouble(
evaltime);
249#ifdef USE_BYTECODE_WHITELIST
266 PyGILState_STATE gilstate;
267 const bool use_gil =
true;
269 gilstate = PyGILState_Ensure();
276 PyGILState_Release(gilstate);
289 const char *null_str =
"<null>";
293 "Error in PyDriver: expression failed: %s\n"
294 "For target: (type=%s, name=\"%s\", property=%s, property_index=%d)\n"
298 id ? id->
name + 2 : null_str,
307#ifdef USE_BYTECODE_WHITELIST
323# if PY_VERSION_HEX < 0x030c0000
324 OK_OP(UNARY_POSITIVE)
326 OK_OP(UNARY_NEGATIVE)
329# if PY_VERSION_HEX < 0x030e0000
333# if PY_VERSION_HEX < 0x030c0000
344# if PY_VERSION_HEX < 0x030c0000
345 OK_OP(JUMP_IF_FALSE_OR_POP)
346 OK_OP(JUMP_IF_TRUE_OR_POP)
347 OK_OP(POP_JUMP_FORWARD_IF_FALSE)
348 OK_OP(POP_JUMP_FORWARD_IF_TRUE)
357# if PY_VERSION_HEX < 0x030c0000
358 OK_OP(POP_JUMP_FORWARD_IF_NOT_NONE)
359 OK_OP(POP_JUMP_FORWARD_IF_NONE)
374# if PY_VERSION_HEX < 0x030c0000
375 OK_OP(POP_JUMP_BACKWARD_IF_NOT_NONE)
376 OK_OP(POP_JUMP_BACKWARD_IF_NONE)
377 OK_OP(POP_JUMP_BACKWARD_IF_FALSE)
378 OK_OP(POP_JUMP_BACKWARD_IF_TRUE)
385# if PY_VERSION_HEX >= 0x030d0000
388 OK_OP(CALL_FUNCTION_EX);
391 OK_OP(CALL_ALLOC_AND_ENTER_INIT)
392 OK_OP(CALL_BOUND_METHOD_EXACT_ARGS)
393 OK_OP(CALL_BOUND_METHOD_GENERAL)
394 OK_OP(CALL_BUILTIN_CLASS)
395 OK_OP(CALL_BUILTIN_FAST)
396 OK_OP(CALL_BUILTIN_FAST_WITH_KEYWORDS)
397 OK_OP(CALL_BUILTIN_O)
398 OK_OP(CALL_ISINSTANCE)
400 OK_OP(CALL_LIST_APPEND)
401 OK_OP(CALL_METHOD_DESCRIPTOR_FAST)
402 OK_OP(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS)
403 OK_OP(CALL_METHOD_DESCRIPTOR_NOARGS)
404 OK_OP(CALL_METHOD_DESCRIPTOR_O)
405 OK_OP(CALL_NON_PY_GENERAL)
406 OK_OP(CALL_PY_EXACT_ARGS)
407 OK_OP(CALL_PY_GENERAL)
415# if PY_VERSION_HEX < 0x030c0000
425 PyObject *py_namespace_array[],
427 const char *error_prefix)
429 PyCodeObject *py_code = (PyCodeObject *)expr_code;
433 for (
int i = 0;
i < PyTuple_GET_SIZE(py_code->co_names);
i++) {
434 PyObject *name = PyTuple_GET_ITEM(py_code->co_names,
i);
435 const char *name_str = PyUnicode_AsUTF8(name);
436 bool contains_name =
false;
437 for (
int j = 0; py_namespace_array[j]; j++) {
438 if (PyDict_Contains(py_namespace_array[j], name)) {
439 contains_name =
true;
444 if ((contains_name ==
false) || (name_str[0] ==
'_')) {
447 "\t%s: restricted access disallows name '%s', "
448 "enable auto-execution to support\n",
459 const _Py_CODEUNIT *codestr;
464 co_code = PyCode_GetCode(py_code);
471 PyBytes_AsStringAndSize(co_code, (
char **)&codestr, &code_len);
472 code_len /=
sizeof(*codestr);
476 for (Py_ssize_t
i = 0;
i < code_len;
i++) {
477 const int opcode = _Py_OPCODE(codestr[
i]);
481 "\t%s: restricted access disallows opcode '%d', "
482 "enable auto-execution to support\n",
501 PyObject *py_namespace,
507 fprintf(stderr,
"%s: couldn't create Python dictionary\n", __func__);
511 PyObject *py_namespaces[] = {
535 PyObject *driver_vars =
nullptr;
536 PyObject *retval =
nullptr;
542 PyGILState_STATE gilstate;
548 bool targets_ok =
true;
553 if (expr[0] ==
'\0') {
557#ifndef USE_BYTECODE_WHITELIST
561 SNPRINTF(
G.autoexec_fail,
"Driver '%s'", expr);
563 printf(
"skipping driver '%s', automatic scripts are disabled\n", expr);
569 bool is_recompile =
false;
575 gilstate = PyGILState_Ensure();
584 fprintf(stderr,
"%s: couldn't create Python dictionary\n", __func__);
586 PyGILState_Release(gilstate);
613 expr_code = Py_CompileString(expr,
"<bpy driver>", Py_eval_input);
614 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 0, expr_code);
622#ifdef USE_BYTECODE_WHITELIST
627 expr_code = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 0);
632 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 1);
633 Py_XDECREF(expr_vars);
636 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 1, expr_vars);
641 PyTuple_SET_ITEM(expr_vars,
i++, PyUnicode_FromString(dvar->
name));
647 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 1);
651 driver_vars = _PyDict_NewPresized(PyTuple_GET_SIZE(expr_vars));
653 PyObject *driver_arg =
nullptr;
656#ifdef USE_RNA_AS_PYOBJECT
659 anim_eval_context, driver, dvar, &dvar->
targets[0]);
661 if (driver_arg ==
nullptr) {
662 driver_arg = PyFloat_FromDouble(0.0);
667 if (PyFloat_CheckExact(driver_arg)) {
668 dvar->
curval = float(PyFloat_AsDouble(driver_arg));
670 else if (PyLong_CheckExact(driver_arg)) {
671 dvar->
curval = float(PyLong_AsLong(driver_arg));
673 else if (PyBool_Check(driver_arg)) {
674 dvar->
curval = float(driver_arg == Py_True);
686 driver_arg = PyFloat_FromDouble(
double(tval));
691 if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars,
i++), driver_arg) != -1) {
698 fprintf(stderr,
"\n%s: Error while evaluating PyDriver:\n", __func__);
702 fprintf(stderr,
"\t%s: couldn't add variable '%s' to namespace\n", __func__, dvar->
name);
707 Py_DECREF(driver_arg);
710#ifdef USE_BYTECODE_WHITELIST
711 if (is_recompile && expr_code) {
713 PyObject *py_namespaces[] = {
724 SNPRINTF(
G.autoexec_fail,
"Driver '%s'", expr);
727 Py_DECREF(expr_code);
729 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 0,
nullptr);
742 retval = PyEval_EvalCode(
748 Py_DECREF(driver_vars);
751 if (retval ==
nullptr) {
755 if (
UNLIKELY((
result = PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred())) {
767 PyGILState_Release(gilstate);
771 fprintf(stderr,
"\t%s: driver '%s' evaluates to '%f'\n", __func__, driver->
expression,
result);
float driver_get_variable_value(const struct AnimationEvalContext *anim_eval_context, struct ChannelDriver *driver, struct DriverVar *dvar)
@ G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET
@ G_FLAG_SCRIPT_AUTOEXEC_FAIL
const char * BKE_idtype_idcode_to_name(short idcode)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define SNPRINTF(dst, format,...)
@ DRIVER_FLAG_PYTHON_BLOCKED
static PyObject * bpy_pydriver_Dict__whitelist
static bool is_opcode_secure(const int opcode)
PyObject * bpy_pydriver_Dict
static void bpy_pydriver_namespace_update_depsgraph(Depsgraph *depsgraph)
static void pydriver_error(ChannelDriver *driver, const PathResolvedRNA *anim_rna)
static void bpy_pydriver_namespace_update_self(PathResolvedRNA *anim_rna)
float BPY_driver_exec(PathResolvedRNA *anim_rna, ChannelDriver *driver, ChannelDriver *driver_orig, const AnimationEvalContext *anim_eval_context)
static struct @324011374074271332033343051256216376352075220253 g_pydriver_state_prev
BPy_StructRNA * depsgraph
static void bpy_pydriver_namespace_update_frame(const float evaltime)
int bpy_pydriver_create_dict()
bool BPY_driver_secure_bytecode_test_ex(PyObject *expr_code, PyObject *py_namespace_array[], const bool verbose, const char *error_prefix)
static PyObject * bpy_pydriver_depsgraph_as_pyobject(Depsgraph *depsgraph)
static void bpy_pydriver_namespace_clear_self()
bool BPY_driver_secure_bytecode_test(PyObject *expr_code, PyObject *py_namespace, const bool verbose)
PyObject * bpy_intern_str_depsgraph
PyObject * bpy_intern_str_self
PyObject * bpy_intern_str_frame
void BPY_update_rna_module()
PyObject * pyrna_struct_CreatePyObject(PointerRNA *ptr)
PyObject * pyrna_driver_get_variable_value(const AnimationEvalContext *anim_eval_context, ChannelDriver *driver, DriverVar *dvar, DriverTarget *dtar)
PyObject * pyrna_driver_self_from_anim_rna(PathResolvedRNA *anim_rna)
bool pyrna_driver_is_equal_anim_rna(const PathResolvedRNA *anim_rna, const PyObject *py_anim_rna)
VecBase< float, D > constexpr mod(VecOp< float, D >, VecOp< float, D >) RET
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
const char * RNA_property_identifier(const PropertyRNA *prop)
#define CALL(member, value_str)
struct Depsgraph * depsgraph