This is needed for C functions to call methods with keyword arguments.
This is a copy of rb_funcall_with_block with an extra argument for
the keyword flag.
There isn't a clean way to implement this that doesn't involve
changing a lot of function signatures, because rb_call doesn't
support a way to mark that the call has keyword arguments. So hack
this in using a CALL_PUBLIC_KW call_type, which we switch for
CALL_PUBLIC later in the call stack.
We do need to modify rm_vm_call0 to take an argument for whether
keyword arguments are used, since the call_type is no longer
available at that point. Use the passed in value to set the
appropriate keyword flag in both calling and ci_entry.
Why not cache the method entry at each caller site. The void**
is in fact a method entry, but this struct is hidden from ruby.h
so intentionally left opaque.
It seems the combination fails at the moment. Don't know exactly
why but I suspect there can be issues in resolving weak references.
Let's rule them out for now.
27036383/job/x3c5d54839aacoyt
We can check the function pointer passed to rb_define_private_method
like how we do so in rb_define_method. Doing so revealed some
problematic usages of rb_obj_dummy. They had to be split according
to their arity.
We can check the function pointer passed to
rb_define_protected_method like how we do so in rb_define_method.
This changeset revealed no prototypes mismatches.
We can check the function pointer passed to rb_define_method_id
like how we do so in rb_define_method. This method is relatively
rarely used so there are less problems found than the other APIs.
We can check the function pointer passed to rb_define_global_function
like we do so in rb_define_method. It turns out that almost anybody
is misunderstanding the API.
We can check the function pointer passed to rb_define_module_function
like how we do so in rb_define_method. The difference is that this
changeset reveales lots of atiry mismatches.
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 200e0ee2fd.
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.
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct. This commit adds a function
prototype for rb_ivar_foreach. Luckily this change revealed no
problematic usage of the function.
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct. This commit adds function prototypes
for rb_hash_foreach / st_foreach_safe. Also fixes some prototype
mismatches.
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct. This commit uses rb_gvar_getter_t /
rb_gvar_setter_t for rb_define_hooked_variable /
rb_define_virtual_variable which revealed lots of function prototype
inconsistencies. Some of them were literally decades old, going back
to dda5dc00cf.
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct. This commit adds function prototypes
for struct st_hash_type. Honestly I don't understand why they were
commented out at the first place.
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct. This commit deletes ANYARGS from
st_foreach. I strongly believe that this commit should have had come
with b0af0592fd, which added extra
parameter to st_foreach callbacks.
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct. This commit deletes ANYARGS from
rb_thread_create, which seems very safe to do.
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct. This commit deletes ANYARGS from
rb_proc_new / rb_fiber_new, and applies RB_BLOCK_CALL_FUNC_ARGLIST
wherever necessary.
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct. This commit deletes ANYARGS from
rb_catch, and fixes some bugs revealed by that.
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct. This commit deletes ANYARGS from
rb_ensure, which also revealed many arity / type mismatches.
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct. This commit deletes ANYARGS from
rb_rescue / rb_rescue2, which revealed many arity / type mismatches.
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct. Let's start from making
rb_block_call_func_t strict, and apply RB_BLOCK_CALL_FUNC_ARGLIST liberally.
Renaming this function. "No pin" leaks some implementation details. We
just want users to know that if they mark this object, the reference may
move and they'll need to update the reference accordingly.
It caused a significant benchmark fall. Some assertions seem to
use expressions with side-effects which cannot be inlined.
This reverts commit b452c03a14.
Same as last commit, make some fields `const`.
include/ruby/ruby.h:
* Rasic::klass
* RArray::heap::aux::shared_root
* RRegexp::src
internal.h:
* rb_classext_struct::origin_, redefined_class
* vm_svar::cref_or_me, lastline, backref, others
* vm_throw_data::throw_obj
* vm_ifunc::data
* MEMO::v1, v2, u3::value
While modifying this patch, I found write-barrier miss on
rb_classext_struct::redefined_class.
Also vm_throw_data::throw_state is only `int` so change the type.
Shared arrays created by Array#dup and so on points
a shared_root object to manage lifetime of Array buffer.
However, sometimes shared_root is called only shared so
it is confusing. So I fixed these wording "shared" to "shared_root".
* RArray::heap::aux::shared -> RArray::heap::aux::shared_root
* ARY_SHARED() -> ARY_SHARED_ROOT()
* ARY_SHARED_NUM() -> ARY_SHARED_ROOT_REFCNT()
Also, add some debug_counters to count shared array objects.
* ary_shared_create: shared ary by Array#dup and so on.
* ary_shared: finished in shard.
* ary_shared_root_occupied: shared_root but has only 1 refcnt.
The number (ary_shared - ary_shared_root_occupied) is meaningful.