Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Tue, 31 Jul 2018 23:01:29 +0000 (09:01 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 31 Jul 2018 23:01:29 +0000 (09:01 +1000)
1  2 
source/blender/python/intern/bpy_driver.c

index d3464ea58412140ee6e9376c30f3ad12be769eb1,e7608e93f58a3ae42fe879163243805325db6eba..a94708c06028ed25a372584cfebb345e29789dda
@@@ -48,8 -48,6 +48,8 @@@
  
  #include "bpy_driver.h"
  
 +#include "BPY_extern.h"
 +
  extern void BPY_update_rna_module(void);
  
  #define USE_RNA_AS_PYOBJECT
@@@ -254,7 -252,7 +254,7 @@@ static void pydriver_error(ChannelDrive
  
  #define OK_OP(op) [op] = 1
  
- const char secure_opcodes[255] = {
static const char secure_opcodes[255] = {
        OK_OP(POP_TOP),
        OK_OP(ROT_TWO),
        OK_OP(ROT_THREE),
@@@ -383,12 -381,8 +383,12 @@@ static bool bpy_driver_secure_bytecode_
   * (new)note: checking if python is running is not threadsafe [#28114]
   * now release the GIL on python operator execution instead, using
   * PyEval_SaveThread() / PyEval_RestoreThread() so we don't lock up blender.
 + *
 + * For copy-on-write we always cache expressions and write errors in the
 + * original driver, otherwise these would get freed while editing. Due to
 + * the GIL this is thread-safe.
   */
 -float BPY_driver_exec(struct PathResolvedRNA *anim_rna, ChannelDriver *driver, const float evaltime)
 +float BPY_driver_exec(struct PathResolvedRNA *anim_rna, ChannelDriver *driver, ChannelDriver *driver_orig, const float evaltime)
  {
        PyObject *driver_vars = NULL;
        PyObject *retval = NULL;
        int i;
  
        /* get the py expression to be evaluated */
 -      expr = driver->expression;
 +      expr = driver_orig->expression;
        if (expr[0] == '\0')
                return 0.0f;
  
        /* update global namespace */
        bpy_pydriver_namespace_update_frame(evaltime);
  
 -      if (driver->flag & DRIVER_FLAG_USE_SELF) {
 +      if (driver_orig->flag & DRIVER_FLAG_USE_SELF) {
                bpy_pydriver_namespace_update_self(anim_rna);
        }
        else {
                bpy_pydriver_namespace_clear_self();
        }
  
 -      if (driver->expr_comp == NULL)
 -              driver->flag |= DRIVER_FLAG_RECOMPILE;
 +      if (driver_orig->expr_comp == NULL)
 +              driver_orig->flag |= DRIVER_FLAG_RECOMPILE;
  
        /* compile the expression first if it hasn't been compiled or needs to be rebuilt */
 -      if (driver->flag & DRIVER_FLAG_RECOMPILE) {
 -              Py_XDECREF(driver->expr_comp);
 -              driver->expr_comp = PyTuple_New(2);
 +      if (driver_orig->flag & DRIVER_FLAG_RECOMPILE) {
 +              Py_XDECREF(driver_orig->expr_comp);
 +              driver_orig->expr_comp = PyTuple_New(2);
  
                expr_code = Py_CompileString(expr, "<bpy driver>", Py_eval_input);
 -              PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 0, expr_code);
 +              PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 0, expr_code);
  
 -              driver->flag &= ~DRIVER_FLAG_RECOMPILE;
 -              driver->flag |= DRIVER_FLAG_RENAMEVAR; /* maybe this can be removed but for now best keep until were sure */
 +              driver_orig->flag &= ~DRIVER_FLAG_RECOMPILE;
 +              driver_orig->flag |= DRIVER_FLAG_RENAMEVAR; /* maybe this can be removed but for now best keep until were sure */
  #ifdef USE_BYTECODE_WHITELIST
                is_recompile = true;
  #endif
        }
        else {
 -              expr_code = PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 0);
 +              expr_code = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 0);
        }
  
 -      if (driver->flag & DRIVER_FLAG_RENAMEVAR) {
 +      if (driver_orig->flag & DRIVER_FLAG_RENAMEVAR) {
                /* may not be set */
 -              expr_vars = PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1);
 +              expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 1);
                Py_XDECREF(expr_vars);
  
 -              expr_vars = PyTuple_New(BLI_listbase_count(&driver->variables));
 -              PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 1, expr_vars);
 +              expr_vars = PyTuple_New(BLI_listbase_count(&driver_orig->variables));
 +              PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 1, expr_vars);
  
 -              for (dvar = driver->variables.first, i = 0; dvar; dvar = dvar->next) {
 +              for (dvar = driver_orig->variables.first, i = 0; dvar; dvar = dvar->next) {
                        PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_FromString(dvar->name));
                }
  
 -              driver->flag &= ~DRIVER_FLAG_RENAMEVAR;
 +              driver_orig->flag &= ~DRIVER_FLAG_RENAMEVAR;
        }
        else {
 -              expr_vars = PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1);
 +              expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 1);
        }
  
        /* add target values to a dict that will be used as '__locals__' dict */
                        {
                                Py_DECREF(expr_code);
                                expr_code = NULL;
 -                              PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 0, NULL);
 +                              PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 0, NULL);
                        }
                }
        }