diff options
author | 卜部昌平 <[email protected]> | 2019-08-28 17:11:23 +0900 |
---|---|---|
committer | 卜部昌平 <[email protected]> | 2019-08-29 18:34:09 +0900 |
commit | 9ef51b0b89a10c8c401cb9f2337e47a25be72cbe (patch) | |
tree | 511f7b67ffb9a22c9028aef0c9f4346835348578 /include/ruby/intern.h | |
parent | 48e346a088395924298163941d4b4cdd8243e377 (diff) |
drop-in type check for rb_define_method
The rb_define_method function takes a pointer to ANYARGS-ed functions,
which in fact varies 18 different prototypes. We still need to
preserve ANYARGS for storages but why not check the consistencies if
possible.
Q&As:
Q: Where did the magic number "18" came from in the description above?
A: Count the case branch of vm_method.c:call_cfunc_invoker_func().
Note also that the 18 branches has lasted for at least 25 years.
See also 200e0ee2fd3c1c006c528874a88f684447215524.
Q: What is this __weakref__ thing?
A: That is a kind of function overloading mechanism that GCC provides.
In this case for instance rb_define_method0 is an alias of
rb_define_method, with a strong type.
Q: What is this __transparent_union__ thing?
A: That is another kind of function overloading mechanism that GCC
provides. In this case the attributed function pointer is either
VALUE(*)(int,VALUE*,VALUE) or VALUE(*)(int,const VALUE*,VALUE).
This is better than void* or ANYARGS because we can reject all
other possibilities than the two.
Q: What does this rb_define_method macro mean?
A: It selects appropriate alias of the rb_define_method function,
depending on the arity.
Q: Why the prototype change of rb_f_notimplement?
A: Function pointer to rb_f_notimplement is special cased in
vm_method.c:rb_add_method_cfunc(). That should be handled by the
__builtin_choose_expr chain inside of rb_define_method macro
expansion. In order to do so, comparison like (func ==
rb_f_notimplement) is inappropriate for __builtin_choose_expr's
expression (which must be a compile-time integer constant but the
address of rb_f_notimplement is not fixed until the linker). So
instead we are using __builtin_types_compatible_p, and in doing so
we need to distinguish rb_f_notimplement from others, by type.
Diffstat (limited to 'include/ruby/intern.h')
-rw-r--r-- | include/ruby/intern.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/include/ruby/intern.h b/include/ruby/intern.h index 3e418c3911..612808875f 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -421,9 +421,9 @@ int rb_method_basic_definition_p(VALUE, ID); VALUE rb_eval_cmd(VALUE, VALUE, int); int rb_obj_respond_to(VALUE, ID, int); int rb_respond_to(VALUE, ID); -NORETURN(VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj)); +NORETURN(VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj, VALUE marker)); #if !defined(RUBY_EXPORT) && defined(_WIN32) -RUBY_EXTERN VALUE (*const rb_f_notimplement_)(int, const VALUE *, VALUE); +RUBY_EXTERN VALUE (*const rb_f_notimplement_)(int, const VALUE *, VALUE, VALUE marker); #define rb_f_notimplement (*rb_f_notimplement_) #endif NORETURN(void rb_interrupt(void)); |