From cb1f9fe9184c67f9a99f6a9702559293613b7e80 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 20 Sep 2019 16:48:42 +0900 Subject: [PATCH] Check various method defitions in C++ --- ext/-test-/cxxanyargs/cxxanyargs.cpp | 44 ++++++++++++++++++++++++++++ include/ruby/ruby.h | 36 ++++++++++++++++------- 2 files changed, 70 insertions(+), 10 deletions(-) diff --git a/ext/-test-/cxxanyargs/cxxanyargs.cpp b/ext/-test-/cxxanyargs/cxxanyargs.cpp index c0117b3633..9a800cbeda 100644 --- a/ext/-test-/cxxanyargs/cxxanyargs.cpp +++ b/ext/-test-/cxxanyargs/cxxanyargs.cpp @@ -337,6 +337,49 @@ namespace test_rb_ivar_foreach { } } +namespace test_rb_define_method { + static VALUE + m1(VALUE, VALUE) + { + return Qnil; + } + + static VALUE + m2(VALUE, VALUE, VALUE) + { + return Qnil; + } + + static VALUE + ma(VALUE, VALUE) + { + return Qnil; + } + + static VALUE + mv(int, VALUE*, VALUE) + { + return Qnil; + } + + VALUE + test(VALUE self) + { + // No cast + rb_define_method(self, "m1", m1, 1); + rb_define_method(self, "m2", m2, 2); + rb_define_method(self, "ma", ma, -2); + rb_define_method(self, "mv", mv, -1); + + // Cast by RUBY_METHOD_FUNC + rb_define_method(self, "m1", RUBY_METHOD_FUNC(m1), 1); + rb_define_method(self, "m2", RUBY_METHOD_FUNC(m2), 2); + rb_define_method(self, "ma", RUBY_METHOD_FUNC(ma), -2); + rb_define_method(self, "mv", RUBY_METHOD_FUNC(mv), -1); + return self; + } +} + extern "C" void Init_cxxanyargs(void) { @@ -361,4 +404,5 @@ Init_cxxanyargs(void) test(st_foreach_safe); test(rb_hash_foreach); test(rb_ivar_foreach); + test(rb_define_method); } diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index 1edde16fdc..ad86f28253 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -2711,12 +2711,24 @@ RUBY_SYMBOL_EXPORT_END # define rb_f_notimplement_p(f) 0 #endif -#if defined(__has_attribute) && (defined(__cplusplus) || defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)) && !defined(_WIN32) && !defined(__CYGWIN__) -#if (defined(__cplusplus) || __has_attribute(transparent_union)) && __has_attribute(unused) && __has_attribute(weakref) && __has_attribute(nonnull) +#if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P) +#if defined(__has_attribute) && __has_attribute(transparent_union) && __has_attribute(unused) && __has_attribute(weakref) && __has_attribute(nonnull) +#define RB_METHOD_DEFINITION_DECL_C(def,nonnull,defname,decl,vars,funcargs) \ + __attribute__((__unused__,__weakref__(#def),__nonnull__ nonnull))static void defname(RB_UNWRAP_MACRO decl,VALUE(*func)funcargs,int arity); +#endif +#endif + +#if defined(RB_METHOD_DEFINITION_DECL_C) || defined(__cplusplus) +#ifndef RB_METHOD_DEFINITION_DECL_C +#define RB_METHOD_DEFINITION_DECL_C(def,nonnull,defname,decl,vars,funcargs) \ + static inline void defname(RB_UNWRAP_MACRO decl,VALUE(*func)funcargs,int arity) \ + { \ + def(RB_UNWRAP_MACRO vars,(VALUE(*)(ANYARGS))(func),arity); \ + } +#endif #define RB_UNWRAP_MACRO(...) __VA_ARGS__ -#define RB_METHOD_DEFINITION_DECL_C(def,nonnull,defname,decl,funcargs) \ - __attribute__((__unused__,__weakref__(#def),__nonnull__ nonnull))static void defname(RB_UNWRAP_MACRO decl,VALUE(*func)funcargs,int arity); + #ifdef __cplusplus #define RB_METHOD_DEFINITION_DECL_CXX_BEGIN(def) template struct def##_tmpl {}; #define RB_METHOD_DEFINITION_DECL_CXX(def,defname,decl,vars,funcargs,arity) \ @@ -2728,7 +2740,7 @@ RUBY_SYMBOL_EXPORT_END #define RB_METHOD_DEFINITION_DECL_CXX(def,defname,decl,vars,funcargs,arity) /* nothing */ #endif #define RB_METHOD_DEFINITION_DECL_1(def,nonnull,defname,arity,decl,vars,funcargs) \ - RB_METHOD_DEFINITION_DECL_C(def,nonnull,defname,decl,funcargs) \ + RB_METHOD_DEFINITION_DECL_C(def,nonnull,defname,decl,vars,funcargs) \ RB_METHOD_DEFINITION_DECL_CXX(def,defname,decl,vars,funcargs,arity) #define RB_METHOD_DEFINITION_DECL(def,nonnull,decl,vars) \ @@ -2754,15 +2766,19 @@ RB_METHOD_DEFINITION_DECL_1(def,nonnull,def##m2,-2,decl,vars,(VALUE,VALUE)) \ RB_METHOD_DEFINITION_DECL_M1(def,nonnull,def##m1,decl,vars) /* END */ #ifdef __cplusplus #define RB_METHOD_DEFINITION_DECL_M1(def,nonnull,defname,decl,vars) \ - RB_METHOD_DEFINITION_DECL_C(def,nonnull,defname,decl,(int,VALUE*,VALUE)) \ - RB_METHOD_DEFINITION_DECL_C(def,nonnull,defname,decl,(int,const VALUE*,VALUE)) \ - RB_METHOD_DEFINITION_DECL_C(def,nonnull,defname,decl,(int,const VALUE*,VALUE,VALUE)) + RB_METHOD_DEFINITION_DECL_C(def,nonnull,defname,decl,vars,(int,VALUE*,VALUE)) \ + RB_METHOD_DEFINITION_DECL_C(def,nonnull,defname,decl,vars,(int,const VALUE*,VALUE)) \ + RB_METHOD_DEFINITION_DECL_C(def,nonnull,defname,decl,vars,(int,const VALUE*,VALUE,VALUE)) \ + template <> struct def##_tmpl<-1> { \ + static void define(RB_UNWRAP_MACRO decl, VALUE (*func)(int,VALUE*,VALUE)) {::defname(RB_UNWRAP_MACRO vars, func, -1);} \ + static void define(RB_UNWRAP_MACRO decl, VALUE (*func)(int,const VALUE*,VALUE)) {::defname(RB_UNWRAP_MACRO vars, func, -1);} \ + static void define(RB_UNWRAP_MACRO decl, VALUE (*func)(int,const VALUE*,VALUE,VALUE)) {::defname(RB_UNWRAP_MACRO vars, func, -1);} \ + }; #else #define RB_METHOD_DEFINITION_DECL_M1(def,nonnull,defname,decl,vars) \ - RB_METHOD_DEFINITION_DECL_C(def,nonnull,defname,decl,(int,union{VALUE*x;const VALUE*y;}__attribute__((__transparent_union__)),VALUE)) + RB_METHOD_DEFINITION_DECL_C(def,nonnull,defname,decl,vars,(int,union{VALUE*x;const VALUE*y;}__attribute__((__transparent_union__)),VALUE)) #endif -#endif #endif #ifdef RB_METHOD_DEFINITION_DECL