Mercurial > octave
changeset 23518:8744d4ed8fb4
provide DEFMETHOD macros
Allow a reference to the interpreter object to be passed to built-in
interpreter functions.
* find-defun-files.sh: Adjust regexp pattern for finding built-in
functions.
* mk-builtins.pl: Handle DEFMETHOD variants of built-in function macros.
* defun-int.h, defun.cc (install_builtin_function):
New overloads for methods.
* defun-int.h (FORWARD_DECLARE_METHODX, FORWARD_DECLARE_METHOD,
DECLARE_METHODX, DECLARE_METHOD, DECLARE_STATIC_METHODX,
DECLARE_STATIC_METHOD): New macros.
* defun.h (DEFMETHOD, DEFMETHODX, DEFCONSTMETHOD): New macros.
* libinterp/gendoc.pl: Likewise.
* ov-builtin.h, ov-builtin.cc (octave_builtin::meth): New typedef.
(octave_builtin::m): New data member.
(octave_builtin::method): New function.
(octave_builtin::octave_builtin, octave_builtin::call):
Handle methods.
* ov-dld-fcn.h, ov-dld-fcn.cc (octave_dld_function::create,
octave_dld_function::octave_dld_function): Handle methods.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 19 May 2017 16:01:18 -0400 |
parents | 1bc8f1f50b54 |
children | 4fe410bd918d |
files | build-aux/find-defun-files.sh build-aux/mk-builtins.pl libinterp/corefcn/defun-int.h libinterp/corefcn/defun.cc libinterp/corefcn/defun.h libinterp/gendoc.pl libinterp/octave-value/ov-builtin.cc libinterp/octave-value/ov-builtin.h libinterp/octave-value/ov-dld-fcn.cc libinterp/octave-value/ov-dld-fcn.h |
diffstat | 10 files changed, 188 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- a/build-aux/find-defun-files.sh Fri May 19 15:53:32 2017 -0400 +++ b/build-aux/find-defun-files.sh Fri May 19 16:01:18 2017 -0400 @@ -27,7 +27,7 @@ # so we have to repeat ourselves because some stupid egreps don't like # empty elements in alternation patterns. -DEFUN_PATTERN="^[ \t]*DEF(CONSTFUN|UN|UN_DLD|UNX|UNX_DLD)[ \t]*\\(" +DEFUN_PATTERN="^[ \t]*DEF(CONSTFUN|METHOD|METHOD_DLD|METHODX|METHODX_DLD|UN|UN_DLD|UNX|UNX_DLD)[ \t]*\\(" srcdir="$1" if [ "$1" ]; then
--- a/build-aux/mk-builtins.pl Fri May 19 15:53:32 2017 -0400 +++ b/build-aux/mk-builtins.pl Fri May 19 16:01:18 2017 -0400 @@ -71,6 +71,11 @@ #include \"ovl.h\" +namespace octave +{ + class interpreter; +} + "; while ($file = shift (@ARGV)) @@ -88,33 +93,47 @@ while (<$fh>) { - if (/^[ \t]*DEF(CONSTFUN|UN)[ \t]*\( *([^ ,]*).*$/) + if (/^[ \t]*DEF(CONSTFUN|CONSTMETHOD|METHOD|UN)[ \t]*\( *([^ ,]*).*$/) { $name = "F$2"; + $is_method = ($1 eq "METHOD" || $1 eq "CONSTMETHOD"); } - elsif (/^[ \t]*DEFUNX[ \t]*\( *"[^"]*" *, *([^ ,]*).*$/) + elsif (/^[ \t]*DEF(METHOD|UN)X[ \t]*\( *"[^"]*" *, *([^ ,]*).*$/) { - $name = $1; + $name = $2; + $is_method = ($1 eq "METHOD"); } elsif ($defun_dld_are_built_in) { - if (/^[ \t]*DEFUN_DLD[ \t]*\( *([^ ,]*).*$/) + if (/^[ \t]*DEF(METHOD|UN)_DLD[ \t]*\( *([^ ,]*).*$/) { - $name = "F$1"; + $name = "F$2"; + $is_method = ($1 eq "METHOD"); } - elsif (/^[ \t]*DEFUNX_DLD[ \t]*\( *"[^"]*" *, *([^ ,]*).*$/) + elsif (/^[ \t]*DEF(METHOD|UN)X_DLD[ \t]*\( *"[^"]*" *, *([^ ,]*).*$/) { - $name = "$1"; + $name = "$2"; + $is_method = ($1 eq "METHOD"); } } if ($name) { - print "extern OCTINTERP_API octave_value_list + if ($is_method) + { + print "extern OCTINTERP_API octave_value_list +$name (octave::interpreter&, const octave_value_list& = octave_value_list (), int = 0); +"; + } + else + { + print "extern OCTINTERP_API octave_value_list $name (const octave_value_list& = octave_value_list (), int = 0); +"; + } -"; $name = ""; + $is_method = 0; } } } @@ -182,23 +201,23 @@ while ($line = <$fh>) { - if ($line =~ /^ *DEFUN *\( *([^ ,]*) *,.*$/) + if ($line =~ /^ *DEF(METHOD|UN) *\( *([^ ,]*) *,.*$/) { $type = "fun"; - $fname = "F$1"; - $name = "$1"; + $fname = "F$2"; + $name = "$2"; } - elsif ($line =~ /^ *DEFUNX *\( *"([^"]*)" *, *([^ ,]*) *,.*$/) + elsif ($line =~ /^ *DEF(METHOD|UN)X *\( *"([^"]*)" *, *([^ ,]*) *,.*$/) { $type = "fun"; - $fname = "$2"; - $name = "$1"; + $fname = "$3"; + $name = "$2"; } - elsif ($line =~ /^ *DEFCONSTFUN *\( *([^ ,]*) *,.*$/) + elsif ($line =~ /^ *DEFCONST(FUN|METHOD) *\( *([^ ,]*) *,.*$/) { $type = "fun"; - $fname = "F$1"; - $name = "$1"; + $fname = "F$2"; + $name = "$2"; $const = 1; } elsif ($line =~ /^ *DEFALIAS *\( *([^ ,]*) *, *([^ )]*) *\).*$/) @@ -209,17 +228,17 @@ } elsif ($defun_dld_are_built_in) { - if ($line =~ /^ *DEFUN_DLD *\( *([^ ,]*) *,.*$/) + if ($line =~ /^ *DEF(METHOD|UN)_DLD *\( *([^ ,]*) *,.*$/) { $type = "fun"; - $fname = "F$1"; - $name = "$1"; + $fname = "F$2"; + $name = "$2"; } - elsif ($line =~ /^ *DEFUNX_DLD *\( *"([^"]*)" *, *([^ ,]*) *,.*$/) + elsif ($line =~ /^ *DEF(METHOD|UN)X_DLD *\( *"([^"]*)" *, *([^ ,]*) *,.*$/) { $type = "fun"; - $fname = "$2"; - $name = "$1"; + $fname = "$3"; + $name = "$2"; } }
--- a/libinterp/corefcn/defun-int.h Fri May 19 15:53:32 2017 -0400 +++ b/libinterp/corefcn/defun-int.h Fri May 19 16:01:18 2017 -0400 @@ -32,6 +32,11 @@ #include "symtab.h" #include "version.h" +namespace octave +{ + class interpreter; +} + class octave_value; extern OCTINTERP_API void print_usage (void); @@ -46,11 +51,21 @@ bool can_hide_function = true); extern OCTINTERP_API void +install_builtin_function (octave_builtin::meth m, const std::string& name, + const std::string& file, const std::string& doc, + bool can_hide_function = true); + +extern OCTINTERP_API void install_dld_function (octave_dld_function::fcn f, const std::string& name, const octave::dynamic_library& shl, const std::string& doc, bool relative = false); extern OCTINTERP_API void +install_dld_function (octave_dld_function::meth m, const std::string& name, + const octave::dynamic_library& shl, const std::string& doc, + bool relative = false); + +extern OCTINTERP_API void install_mex_function (void *fptr, bool fmex, const std::string& name, const octave::dynamic_library& shl, bool relative = false); @@ -101,22 +116,45 @@ extern OCTAVE_EXPORT octave_value_list \ name (const octave_value_list&, int) +#define FORWARD_DECLARE_METHODX(name) \ + extern OCTAVE_EXPORT octave_value_list \ + name (octave::interpreter&, const octave_value_list&, int) + #define FORWARD_DECLARE_FUN(name) \ FORWARD_DECLARE_FUNX (F ## name) +#define FORWARD_DECLARE_METHOD(name) \ + FORWARD_DECLARE_METHODX (F ## name) + #define DECLARE_FUNX(name, args_name, nargout_name) \ OCTAVE_EXPORT octave_value_list \ name (const octave_value_list& args_name, int nargout_name) +#define DECLARE_METHODX(name, interp_name, args_name, nargout_name) \ + OCTAVE_EXPORT octave_value_list \ + name (octave::interpreter& interp_name, \ + const octave_value_list& args_name, int nargout_name) + #define DECLARE_FUN(name, args_name, nargout_name) \ DECLARE_FUNX (F ## name, args_name, nargout_name) +#define DECLARE_METHOD(name, interp_name, args_name, nargout_name) \ + DECLARE_METHODX (F ## name, interp_name, args_name, nargout_name) + #define DECLARE_STATIC_FUNX(name, args_name, nargout_name) \ static octave_value_list \ name (const octave_value_list& args_name, int nargout_name) +#define DECLARE_STATIC_METHODX(name, interp_name, args_name, nargout_name) \ + static octave_value_list \ + name (octave::interpreter& interp_name, \ + const octave_value_list& args_name, int nargout_name) + #define DECLARE_STATIC_FUN(name, args_name, nargout_name) \ - DECLARE_FUNX (F ## name, args_name, nargout_name) + DECLARE_STATIC_FUNX (F ## name, args_name, nargout_name) + +#define DECLARE_STATIC_METHOD(name, interp_name, args_name, nargout_name) \ + DECLARE_STATIC_METHODX (F ## name, interp_name, args_name, nargout_name) // Define the code that will be used to insert the new function into // the symbol table. We look for this name instead of the actual
--- a/libinterp/corefcn/defun.cc Fri May 19 15:53:32 2017 -0400 +++ b/libinterp/corefcn/defun.cc Fri May 19 16:01:18 2017 -0400 @@ -92,6 +92,16 @@ } void +install_builtin_function (octave_builtin::meth m, const std::string& name, + const std::string& file, const std::string& doc, + bool /* can_hide_function -- not yet implemented */) +{ + octave_value fcn (new octave_builtin (m, name, file, doc)); + + symbol_table::install_built_in_function (name, fcn); +} + +void install_dld_function (octave_dld_function::fcn f, const std::string& name, const octave::dynamic_library& shl, const std::string& doc, bool relative) @@ -107,6 +117,21 @@ } void +install_dld_function (octave_dld_function::meth m, const std::string& name, + const octave::dynamic_library& shl, const std::string& doc, + bool relative) +{ + octave_dld_function *fcn = new octave_dld_function (m, shl, name, doc); + + if (relative) + fcn->mark_relative (); + + octave_value fval (fcn); + + symbol_table::install_built_in_function (name, fval); +} + +void install_mex_function (void *fptr, bool fmex, const std::string& name, const octave::dynamic_library& shl, bool relative) {
--- a/libinterp/corefcn/defun.h Fri May 19 15:53:32 2017 -0400 +++ b/libinterp/corefcn/defun.h Fri May 19 16:01:18 2017 -0400 @@ -46,6 +46,9 @@ #define DEFUN(name, args_name, nargout_name, doc) \ DECLARE_FUN (name, args_name, nargout_name) +#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc) \ + DECLARE_METHOD (name, interp_name, args_name, nargout_name) + // This one can be used when 'name' cannot be used directly (if it is // already defined as a macro). In that case, name is already a // quoted string, and the internal name of the function must be passed @@ -54,10 +57,16 @@ #define DEFUNX(name, fname, args_name, nargout_name, doc) \ DECLARE_FUNX (fname, args_name, nargout_name) +#define DEFMETHODX(name, fname, interp_name, args_name, nargout_name, doc) \ + DECLARE_METHODX (fname, interp_name, args_name, nargout_name) + // This is a function with a name that can't be hidden by a variable. #define DEFCONSTFUN(name, args_name, nargout_name, doc) \ DECLARE_FUN (name, args_name, nargout_name) +#define DEFCONSTMETHOD(name, interp_name, args_name, nargout_name, doc) \ + DECLARE_METHOD (name, interp_name, args_name, nargout_name) + // Make alias another name for the existing function name. This macro // is processed by the mkbuiltins to generate code in builtins.cc to // create the alias in the symbol table.
--- a/libinterp/gendoc.pl Fri May 19 15:53:32 2017 -0400 +++ b/libinterp/gendoc.pl Fri May 19 16:01:18 2017 -0400 @@ -48,7 +48,7 @@ LINE: while (my $line = <SRC_FH>) { - if ($line =~ /^\s*DEF(?:CONSTFUN|UN|UN_DLD|UNX|UNX_DLD)\s*\(/) + if ($line =~ /^\s*DEF(?:CONSTFUN|CONSTMETHOD|METHOD|METHOD_DLD|METHODX|METHODX_DLD|UN|UN_DLD|UNX|UNX_DLD)\s*\(/) { ($func) = $line =~ /\("?(\w+)"?,/; unless ($func) { die "Unable to parse $src_fname at line $.\n" }
--- a/libinterp/octave-value/ov-builtin.cc Fri May 19 15:53:32 2017 -0400 +++ b/libinterp/octave-value/ov-builtin.cc Fri May 19 16:01:18 2017 -0400 @@ -27,11 +27,12 @@ #include "call-stack.h" #include "error.h" #include "errwarn.h" -#include "ovl.h" +#include "interpreter-private.h" +#include "interpreter.h" #include "ov-builtin.h" #include "ov.h" +#include "ovl.h" #include "profiler.h" -#include "interpreter.h" #include "unwind-prot.h" @@ -100,7 +101,15 @@ profile_data_accumulator::enter<octave_builtin> block (profiler, *this); - retval = (*f) (args, nargout); + if (f) + retval = (*f) (args, nargout); + else + { + octave::interpreter& interp + = octave::__get_interpreter__ ("octave_builtin::call"); + + retval = (*m) (interp, args, nargout); + } // Do not allow null values to be returned from functions. // FIXME: perhaps true builtins should be allowed? @@ -142,6 +151,12 @@ return f; } +octave_builtin::meth +octave_builtin::method (void) const +{ + return m; +} + void octave_builtin::push_dispatch_class (const std::string& dispatch_type) {
--- a/libinterp/octave-value/ov-builtin.h Fri May 19 15:53:32 2017 -0400 +++ b/libinterp/octave-value/ov-builtin.h Fri May 19 16:01:18 2017 -0400 @@ -36,6 +36,11 @@ class octave_value_list; class jit_type; +namespace octave +{ + class interpreter; +} + // Builtin functions. class @@ -46,15 +51,26 @@ octave_builtin (void) : octave_function (), f (0), file (), jtype (0) { } + typedef octave_value_list (*meth) (octave::interpreter&, + const octave_value_list&, int); + typedef octave_value_list (*fcn) (const octave_value_list&, int); octave_builtin (fcn ff, const std::string& nm = "", const std::string& ds = "") - : octave_function (nm, ds), f (ff), file (), jtype (0) { } + : octave_function (nm, ds), f (ff), m (0), file (), jtype (0) { } + + octave_builtin (meth mm, const std::string& nm = "", + const std::string& ds = "") + : octave_function (nm, ds), f (0), m (mm), file (), jtype (0) { } octave_builtin (fcn ff, const std::string& nm, const std::string& fnm, const std::string& ds) - : octave_function (nm, ds), f (ff), file (fnm), jtype (0) { } + : octave_function (nm, ds), f (ff), m (0), file (fnm), jtype (0) { } + + octave_builtin (meth mm, const std::string& nm, const std::string& fnm, + const std::string& ds) + : octave_function (nm, ds), f (0), m (mm), file (fnm), jtype (0) { } // No copying! @@ -89,6 +105,8 @@ fcn function (void) const; + meth method (void) const; + void push_dispatch_class (const std::string& dispatch_type); bool handles_dispatch_class (const std::string& dispatch_type) const; @@ -97,6 +115,7 @@ // A pointer to the actual function. fcn f; + meth m; // The name of the file where this function was defined. std::string file;
--- a/libinterp/octave-value/ov-dld-fcn.cc Fri May 19 15:53:32 2017 -0400 +++ b/libinterp/octave-value/ov-dld-fcn.cc Fri May 19 16:01:18 2017 -0400 @@ -52,6 +52,20 @@ && Voct_file_dir == file_name.substr (0, Voct_file_dir.length ())); } +octave_dld_function::octave_dld_function + (octave_builtin::meth mm, const octave::dynamic_library& shl, + const std::string& nm, const std::string& ds) + : octave_builtin (mm, nm, ds), sh_lib (shl) +{ + mark_fcn_file_up_to_date (time_parsed ()); + + std::string file_name = fcn_file_name (); + + system_fcn_file + = (! file_name.empty () + && Voct_file_dir == file_name.substr (0, Voct_file_dir.length ())); +} + octave_dld_function::~octave_dld_function (void) { octave::dynamic_loader::remove_oct (my_name, sh_lib); @@ -87,3 +101,11 @@ { return new octave_dld_function (ff, shl, nm, ds); } + +octave_dld_function* +octave_dld_function::create (octave_builtin::meth mm, + const octave::dynamic_library& shl, + const std::string& nm, const std::string& ds) +{ + return new octave_dld_function (mm, shl, nm, ds); +}
--- a/libinterp/octave-value/ov-dld-fcn.h Fri May 19 15:53:32 2017 -0400 +++ b/libinterp/octave-value/ov-dld-fcn.h Fri May 19 16:01:18 2017 -0400 @@ -52,6 +52,10 @@ const std::string& nm = "", const std::string& ds = ""); + octave_dld_function (octave_builtin::meth mm, const octave::dynamic_library& shl, + const std::string& nm = "", + const std::string& ds = ""); + // No copying! octave_dld_function (const octave_dld_function& fn) = delete; @@ -79,6 +83,11 @@ const std::string& nm = "", const std::string& ds = ""); + static octave_dld_function * create (octave_builtin::meth mm, + const octave::dynamic_library& shl, + const std::string& nm = "", + const std::string& ds = ""); + octave::dynamic_library get_shlib (void) const { return sh_lib; }