Page MenuHome
Paste P338

Python sandbox experement, using numba (see: T47823)
ActivePublic

Authored by Campbell Barton (campbellbarton) on Mar 17 2016, 6:17 AM.
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index dd1b4ea..101e2d7 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -189,6 +189,9 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime)
if (expr[0] == '\0')
return 0.0f;
+ bool use_sandbox = (G.f & G_SCRIPT_AUTOEXEC) == 0;
+
+#if 0
if (!(G.f & G_SCRIPT_AUTOEXEC)) {
if (!(G.f & G_SCRIPT_AUTOEXEC_FAIL_QUIET)) {
G.f |= G_SCRIPT_AUTOEXEC_FAIL;
@@ -198,6 +201,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime)
}
return 0.0f;
}
+#endif
use_gil = true; /* !PyC_IsInterpreterActive(); */
@@ -231,6 +235,43 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime)
driver->expr_comp = PyTuple_New(2);
expr_code = Py_CompileString(expr, "<bpy driver>", Py_eval_input);
+
+ if (use_sandbox) {
+ /* # Python version of what we do below:
+ * def sandbox_code(code):
+ * import numba
+ * from types import FunctionType
+ * fn = FunctionType(code, {})
+ * fn_jit = numba.jit(fn, nopython=True)
+ * return fn_jit.__code__
+ */
+ PyInterpreterState *interp = PyThreadState_GET()->interp;
+ /* Should cache this for reuse... */
+ PyObject *expr_code_jit_conv = Py_CompileString(
+ "__import__('numba').jit(__import__('types').FunctionType(code, {}), nopython=True).__code__",
+ "<bpy driver jit>", Py_eval_input);
+ PyObject *expr_code_locals = PyDict_New();
+ PyDict_SetItemString(expr_code_locals, "code", expr_code);
+ PyObject *expr_code_jit = PyEval_EvalCode((void *)expr_code_jit_conv, interp->builtins, expr_code_locals);
+ Py_DECREF(expr_code_jit_conv);
+ Py_DECREF(expr_code_locals);
+
+ if (expr_code_jit == NULL) {
+ fprintf(stderr, "PyDriver error: jit converting expression failed\n");
+ PyErr_Print();
+ PyErr_Clear();
+ if (use_gil)
+ PyGILState_Release(gilstate);
+ return 0.0f;
+ }
+ else {
+ /* swap out with the restricted version */
+ fprintf(stderr, "PyDriver success: using jit for:\n %s\n", expr);
+ Py_DecRef(expr_code);
+ expr_code = expr_code_jit;
+ }
+ }
+
PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 0, expr_code);
driver->flag &= ~DRIVER_FLAG_RECOMPILE;

Event Timeline

Campbell Barton (campbellbarton) changed the title of this paste from untitled to Python sandbox experement, using numba (see: T47823).
Campbell Barton (campbellbarton) updated the paste's language from autodetect to diff.