# HG changeset patch # User Jaroslav Hajek # Date 1264080140 -3600 # Node ID a668fbd32e34bee7f2509b8d6e85de884f6d6568 # Parent be952ce74023db61d3288945628e51de199f8fc2 improve cellfun & avoid undefined values from builtins diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2010-01-21 Jaroslav Hajek + + * ov-base.h (octave_base_value::dim_vector): Return 0x0 by default. + * oct-obj.h (octave_value_list::xelem, octave_value_list::clear): New + methods. + * ov-builtin.cc (octave_builtin::do_multi_index_op): Don't call + make_storable_values. Chop a potential single undefined value. + * ov-type-conv.h (octave_type_conv_body): Ensure storable value. + * ov-dld-fcn.cc (octave_dld_function::do_multi_index_op): New method. + * DLD-FUNCTIONS/cellfun.cc (get_output_list): New helper function. + (Fcellfun): Call it here. Optimize. + 2010-01-20 John W. Eaton * defaults.h.in, graphics.h.in, oct-conf.h.in, oct-errno.cc.in, diff --git a/src/DLD-FUNCTIONS/cellfun.cc b/src/DLD-FUNCTIONS/cellfun.cc --- a/src/DLD-FUNCTIONS/cellfun.cc +++ b/src/DLD-FUNCTIONS/cellfun.cc @@ -223,6 +223,39 @@ return retval; } +static octave_value_list +get_output_list (octave_idx_type count, octave_idx_type nargout, + const octave_value_list& inputlist, + octave_value& func, + octave_value& error_handler) +{ + octave_value_list tmp = func.do_multi_index_op (nargout, inputlist); + + if (error_state) + { + if (error_handler.is_defined ()) + { + Octave_map msg; + msg.assign ("identifier", last_error_id ()); + msg.assign ("message", last_error_message ()); + msg.assign ("index", octave_value(double (count + static_cast(1)))); + octave_value_list errlist = inputlist; + errlist.prepend (msg); + buffer_error_messages--; + error_state = 0; + tmp = error_handler.do_multi_index_op (nargout, errlist); + buffer_error_messages++; + + if (error_state) + tmp.clear (); + } + else + tmp.clear (); + } + + return tmp; +} + DEFUN_DLD (cellfun, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} cellfun (@var{name}, @var{c})\n\ @@ -607,30 +640,14 @@ for (int j = 0; j < nargin; j++) { if (mask[j]) - inputlist(j) = cinputs[j](count); + inputlist.xelem (j) = cinputs[j](count); } - octave_value_list tmp = func.do_multi_index_op (nargout, inputlist); - - if (error_state && error_handler.is_defined ()) - { - Octave_map msg; - msg.assign ("identifier", last_error_id ()); - msg.assign ("message", last_error_message ()); - msg.assign ("index", octave_value(double (count + static_cast(1)))); - octave_value_list errlist = inputlist; - errlist.prepend (msg); - buffer_error_messages--; - error_state = 0; - tmp = error_handler.do_multi_index_op (nargout, errlist); - buffer_error_messages++; - - if (error_state) - return octave_value_list (); - } + const octave_value_list tmp = get_output_list (count, nargout, inputlist, + func, error_handler); if (error_state) - return octave_value_list (); + return retval; if (tmp.length () < nargout1) { @@ -699,30 +716,14 @@ for (int j = 0; j < nargin; j++) { if (mask[j]) - inputlist(j) = cinputs[j](count); + inputlist.xelem (j) = cinputs[j](count); } - octave_value_list tmp = func.do_multi_index_op (nargout, inputlist); - - if (error_state && error_handler.is_defined ()) - { - Octave_map msg; - msg.assign ("identifier", last_error_id ()); - msg.assign ("message", last_error_message ()); - msg.assign ("index", octave_value(double (count + static_cast(1)))); - octave_value_list errlist = inputlist; - errlist.prepend (msg); - buffer_error_messages--; - error_state = 0; - tmp = error_handler.do_multi_index_op (nargout, errlist); - buffer_error_messages++; - - if (error_state) - return octave_value_list (); - } + const octave_value_list tmp = get_output_list (count, nargout, inputlist, + func, error_handler); if (error_state) - return octave_value_list (); + return retval; if (tmp.length () < nargout1) { diff --git a/src/oct-obj.h b/src/oct-obj.h --- a/src/oct-obj.h +++ b/src/oct-obj.h @@ -149,6 +149,16 @@ void make_storable_values (void); + octave_value& xelem (octave_idx_type i) + { + return data.xelem (i); + } + + void clear (void) + { + data.clear (); + } + private: static octave_allocator allocator; diff --git a/src/ov-base.h b/src/ov-base.h --- a/src/ov-base.h +++ b/src/ov-base.h @@ -272,7 +272,7 @@ virtual idx_vector index_vector (void) const; - virtual dim_vector dims (void) const { return dim_vector (-1, -1); } + virtual dim_vector dims (void) const { return dim_vector (); } octave_idx_type rows (void) const { diff --git a/src/ov-builtin.cc b/src/ov-builtin.cc --- a/src/ov-builtin.cc +++ b/src/ov-builtin.cc @@ -105,9 +105,16 @@ try { retval = (*f) (args, nargout); - // Do not allow null values to be returned from functions. - // FIXME -- perhaps true builtins should be allowed? - retval.make_storable_values (); + // We don't check for null values here, builtins should handle that + // possibility themselves. + // Fix the case of a single undefined value. + // This happens when a compiled function uses + // octave_value retval; + // instead of + // octave_value_list retval; + // the idiom is very common, so we solve that here. + if (retval.length () == 1 && retval.xelem (0).is_undefined ()) + retval.clear (); } catch (octave_execution_exception) { diff --git a/src/ov-dld-fcn.cc b/src/ov-dld-fcn.cc --- a/src/ov-dld-fcn.cc +++ b/src/ov-dld-fcn.cc @@ -89,3 +89,14 @@ { return new octave_dld_function (ff, shl, nm, ds); } + +octave_value_list +octave_dld_function::do_multi_index_op (int nargout, const octave_value_list& args) +{ + octave_value_list retval = this->octave_builtin::do_multi_index_op (nargout, args); + // Guard against the possibility of null values leaking from user DLD functions. + // FIXME: is this needed? + retval.make_storable_values (); + + return retval; +} diff --git a/src/ov-dld-fcn.h b/src/ov-dld-fcn.h --- a/src/ov-dld-fcn.h +++ b/src/ov-dld-fcn.h @@ -75,6 +75,9 @@ octave_shlib get_shlib (void) const { return sh_lib; } + octave_value_list + do_multi_index_op (int nargout, const octave_value_list& args); + private: octave_shlib sh_lib; diff --git a/src/ov-type-conv.h b/src/ov-type-conv.h --- a/src/ov-type-conv.h +++ b/src/ov-type-conv.h @@ -32,7 +32,7 @@ if (t_arg == t_result || arg.class_name () == name) { - retval = arg; + retval = arg.storable_value (); } else {