changeset 17810:6da521da1c70

preserve cached mxArray_octave_value data while it's still in use (bug #40429) * mex.cc (mxArray_octave_value::as_mxArray): Transplant cached class_name and dims values to new mxArray object. (mxArray_octave_value::mutate): Call as_mxArray.
author John W. Eaton <jwe@octave.org>
date Wed, 30 Oct 2013 19:04:15 -0400
parents 1631e47a2138
children ef4fc092c86b
files libinterp/corefcn/mex.cc
diffstat 1 files changed, 36 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/mex.cc	Wed Oct 30 14:10:19 2013 -0400
+++ b/libinterp/corefcn/mex.cc	Wed Oct 30 19:04:15 2013 -0400
@@ -168,7 +168,39 @@
 
   mxArray *as_mxArray (void) const
   {
-    return val.as_mxArray ();
+    mxArray *retval = val.as_mxArray ();
+
+    // RETVAL is assumed to be an mxArray_matlab object.  Should we
+    // assert that condition here?
+
+    if (retval)
+      {
+        // Preserve cached values of class name and dimensions in case
+        // they will be used after we mutate.
+
+        // set_class_name will handle deleting class name that comes
+        // from as_mxArray conversion function.
+
+        if (class_name)
+          {
+            retval->set_class_name (class_name);
+
+            class_name = 0;
+          }
+
+        if (dims)
+          {
+            mwSize *xdims = retval->get_dimensions ();
+
+            mxFree (xdims);
+
+            retval->set_dimensions (dims, ndims);
+
+            dims = 0;
+          }
+      }
+
+    return retval;
   }
 
   ~mxArray_octave_value (void)
@@ -526,7 +558,7 @@
     mutate_flag = true;
   }
 
-  mxArray *mutate (void) const { return val.as_mxArray (); }
+  mxArray *mutate (void) const { return as_mxArray (); }
 
   octave_value as_octave_value (void) const { return val; }
 
@@ -2737,8 +2769,8 @@
 void
 mxSetDimensions (mxArray *ptr, const mwSize *dims, mwSize ndims)
 {
-  ptr->set_dimensions (static_cast<mwSize *> (
-                         maybe_unmark (const_cast<mwSize *> (dims))),
+  ptr->set_dimensions (static_cast<mwSize *>
+                       (maybe_unmark (const_cast<mwSize *> (dims))),
                        ndims);
 }