Commit graph

522 commits

Author SHA1 Message Date
卜部昌平
6c6a25feca refactor add rb_method_entry_from_template
Tired of rb_method_entry_create(..., rb_method_definition_create(
..., &(rb_method_foo_t) {...})) maneuver.  Provide a function that
does the thing to reduce copy&paste.
2019-09-30 10:26:38 +09:00
卜部昌平
167e6b48f1 refactor reduce METHOD_ENTRY_FLAGS_COPY
Make things more immutable.
2019-09-30 10:26:38 +09:00
卜部昌平
7cb96d41a5 refactor delete rb_method_entry_copy
The deleted function was to destructively overwrite existing method
entries, which is now considered to be a bad idea.  Delete it, and
assign a newly created method entry instead.
2019-09-30 10:26:38 +09:00
卜部昌平
3207979278 refactor delete rb_method_definition_set
Instead of destructively write fields of method entries, create a
new entry and let it overwrite its owner.
2019-09-30 10:26:38 +09:00
卜部昌平
595b3c4fdd refactor rb_method_definition_create take opts
Before this changeset rb_method_definition_create only allocated a
memory region and we had to destructively initialize it later.
That is not a good design so we change the API to return a complete
struct instead.
2019-09-30 10:26:38 +09:00
卜部昌平
c11c5e69ac refactor split rb_method_definition_set
Did you know that C functions can return structs?  That has been
true since the beginning, but not that very useful until C99.  Now
that we can write compound literals, this feature is much easier
to use.  By allowing struct-returning functions, some formerly big
functions can be split into smaller ones, like this changeset.

At least GCC is smart enough to inline the split functions back
into one.  No performance penalty is observed.
2019-09-30 10:26:38 +09:00
卜部昌平
cf33608203 refactor constify most of rb_method_definition_t
Most (if not all) of the fields of rb_method_definition_t are never
meant to be modified once after they are stored.  Marking them const
makes it possible for compilers to warn on unintended modifications.
2019-09-30 10:26:38 +09:00
卜部昌平
86427a3219 refactor delete METHOD_ENTRY_COMPLEMENTED flag
Because rb_method_definition_t tracks its own complemented_count,
we no longer have to check it in rb_method_entry_t side.
2019-09-30 10:26:38 +09:00
Jeremy Evans
3b302ea8c9 Add Module#ruby2_keywords for passing keywords through regular argument splats
This approach uses a flag bit on the final hash object in the regular splat,
as opposed to a previous approach that used a VM frame flag.  The hash flag
approach is less invasive, and handles some cases that the VM frame flag
approach does not, such as saving the argument splat array and splatting it
later:

  ruby2_keywords def foo(*args)
    @args = args
    bar
  end
  def bar
    baz(*@args)
  end
  def baz(*args, **kw)
    [args, kw]
  end
  foo(a:1)    #=> [[], {a: 1}]
  foo({a: 1}, **{}) #=> [[{a: 1}], {}]

  foo({a: 1}) #=> 2.7: [[], {a: 1}] # and warning
  foo({a: 1}) #=> 3.0: [[{a: 1}], {}]

It doesn't handle some cases that the VM frame flag handles, such as when
the final hash object is replaced using Hash#merge, but those cases are
probably less common and are unlikely to properly support keyword
argument separation.

Use ruby2_keywords to handle argument delegation in the delegate library.
2019-09-25 12:33:52 -07:00
Jeremy Evans
e47b111627 Call rb_vm_call_kw insted of rb_vm_call0 in a few cases
rb_vm_call_kw handles the tmp buffer for you.

Also, change method_missing so it also calls rb_vm_call_kw to
handle the kw_splat flag, instead of requiring callers to handle
kw_splat flag before calling method_missing.  This may fix other
cases where method_missing is currently called without the kw_splat
being handled.
2019-09-20 07:45:29 -07:00
Jeremy Evans
27b6746872 Make passing empty keywords to dig pass empty keywords to next dig method
If defined in Ruby, dig would be defined as def dig(arg, *rest) end,
it would not use keywords.  If the last dig argument was an empty
hash, it could be treated as keyword arguments by the next dig
method.  Allow dig to pass along the empty keyword flag if called
with an empty keyword, to suppress the previous behavior and force
treating the hash as a positional argument and not keywords.

Also handle the case where dig calls method_missing, passing the
empty keyword flag to that as well.

This requires adding rb_check_funcall_with_hook_kw functions, so
that dig can specify how arguments are treated.  It also adds
kw_splat arguments to a couple static functions.
2019-09-20 07:45:11 -07:00
Jeremy Evans
7fc874bf4c Add rb_funcall_with_block_kw
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.
2019-09-05 17:47:12 -07:00
卜部昌平
bfe5d22f89 drop-in type check for rb_define_private_method
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.
2019-08-29 18:34:09 +09:00
卜部昌平
9ef51b0b89 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 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.
2019-08-29 18:34:09 +09:00
Nobuyoshi Nakada
1d11a8b193
Ensure non-OPT_GLOBAL_METHOD_CACHE code valid 2019-08-18 00:34:12 +09:00
Nobuyoshi Nakada
6db3051fcc
Ensure VM_DEBUG_VERIFY_METHOD_CACHE code valid 2019-08-18 00:34:12 +09:00
Jeremy Evans
ef45a57801 Make attr* methods define public methods if self in caller is not same as receiver
Previously, attr* methods could be private even if not in the
private section of a class/module block.

This uses the same approach that ruby started using for define_method
in 1fc3319973.

Fixes [Bug #4537]
2019-08-01 08:52:15 -07:00
svn
481481b81a * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67500 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-10 09:16:00 +00:00
kazu
25c1fd3b90 Reverting all commits from r67479 to r67496 because of CI failures
Because hard to specify commits related to r67479 only.
So please commit again.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67499 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-10 09:15:21 +00:00
nobu
33721b4d33 vm_method.c: fix a warning
* vm_method.c (rb_add_method_iseq): use rb_method_iseq_t, as
  rb_method_definition_set refers, with a cast to suppress a
  warning.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67494 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-10 06:44:42 +00:00
tenderlove
3ef4db15e9 Adding GC.compact and compacting GC support.
This commit adds the new method `GC.compact` and compacting GC support.
Please see this issue for caveats:

  https://bugs.ruby-lang.org/issues/15626

[Feature #15626]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67479 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-09 20:32:04 +00:00
ko1
b2311c6767 rb_add_method is void function.
* method.h (rb_add_method): make it void function because
  nobody use a return value.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67444 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-05 08:41:04 +00:00
svn
4b53f84326 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67443 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-05 08:15:21 +00:00
ko1
2b5bb8a087 add definemethod/definesmethod insn.
* insns.def: add definemethod and definesmethod (singleton method)
  instructions. Old YARV contains these instructions, but it is moved
  to methods of FrozenCore class because remove number of instructions
  can improve performance for some techniques (static stack caching
  and so on). However, we don't employ these technique and it is hard
  to optimize/analysis definition sequence. So I decide to introduce
  them (and remove definition methods). `putiseq` insn is also removed.

* vm_method.c (rb_scope_visibility_get): renamed to
  `vm_scope_visibility_get()` and make it accept `ec`.
  Same for `vm_scope_module_func_check()`.
  These fixes are result of refactoring `vm_define_method`.

* vm_insnhelper.c (rb_vm_get_cref): renamed to `vm_get_cref`
  because of consistency with other functions.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67442 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-05 08:15:11 +00:00
nobu
978290515e [DOC] Fix method references to Method instance methods
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67355 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-28 03:33:36 +00:00
nobu
de0ef1a9df [DOC] fix markups [ci skip]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67354 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-28 03:33:35 +00:00
ko1
b1c1ee7183 change cfunc->invoker type for opt.
* vm_insnhelper.c: change `call_cfunc_*` parameters order
  and specify a function type for the passed func ptr.
  This fix reduce the number of asm instructions, such as:
    # before this patch
    0000000000000110 <call_cfunc_0>:
     110:       48 89 fa                mov    %rdi,%rdx
     113:       31 c0                   xor    %eax,%eax
     115:       48 89 f7                mov    %rsi,%rdi
     118:       ff e2                   jmpq   *%rdx
     11a:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

    # after this patch
    0000000000000110 <call_cfunc_0>:
     110:       ff e1                   jmpq   *%rcx

  However, this kind of instruction reduction doesn't affect
  any performance because of great CPU architectures :p


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67122 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-02-22 07:25:51 +00:00
nobu
2a4c87dc31 Add refinements support to method/instance_method.
[Fix GH-2034]

From: manga_osyo <manga.osyo@gmail.com>

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66935 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-01-28 11:45:21 +00:00
nobu
78d6e33702 Fix styles [ci skip]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66762 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-01-09 13:58:49 +00:00
nobu
75f36bdc1e Constified to fix warning at r66442
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66445 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-18 16:11:07 +00:00
svn
7b6f2e2c90 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66443 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-18 15:11:18 +00:00
nobu
a80cc953aa Expand cross-recursion to a loop
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66442 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-18 15:11:17 +00:00
nobu
188b673973 Enable refinements on symbol-proc in ruby-level methods
* vm_args.c (refine_sym_proc_call): resolve refinements when the
  proc is invoked, instead of resolving at making the proc, to
  enable refinements on symbol-proc in ruby-level methods

* vm.c (vm_cref_dup): clear cached symbol-procs when duplicating.

[Bug #15114] [Fix GH-2039]

From: manga_osyo <manga.osyo@gmail.com>

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66439 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-18 13:59:46 +00:00
nobu
76e3af82d5 Warn redefinitions of some methods on Object
[Bug #5473] [Bug #14670] [Bug #15382]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66262 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-06 23:06:13 +00:00
mrkn
242ce4b1d3 Revert "Symbol refinements"
Due to assertion failures when VM_CHECK_MODE >= 2.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66182 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-04 04:22:08 +00:00
mrkn
01b20daa86 Symbol refinements
* vm_args.c (refine_sym_proc_call): enalbe accidentally disabled
  refinements in Symbol#to_proc.   [Bug #15114]

From: osyo (manga osyo) <manga.osyo@gmail.com>

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66181 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-04 04:22:06 +00:00
nobu
4d1e32eac6 Revert "Symbol refinements"
Due to assertion failures when VM_CHECK_MODE >= 2.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-03 08:51:29 +00:00
nobu
b94e344b9d Symbol refinements
* vm_args.c (refine_sym_proc_call): enalbe accidentally disabled
  refinements in Symbol#to_proc.   [Bug #15114]

From: osyo (manga osyo) <manga.osyo@gmail.com>

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66151 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-03 04:44:34 +00:00
nobu
1a1dd5ccf4 Revert "Symbol refinements [Bug #15114]"
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66150 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-03 04:44:33 +00:00
nobu
cd5b309575 Symbol refinements [Bug #15114]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66149 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-03 04:34:27 +00:00
svn
61c8247d55 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66004 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-26 18:16:54 +00:00
ko1
96990203b7 Support targetting TracePoint [Feature #15289]
* vm_trace.c (rb_tracepoint_enable_for_target): support targetting
  TracePoint. [Feature #15289]

  Tragetting TracePoint is only enabled on specified method, proc
  and so on, example: `tp.enable(target: code)`.

  `code` should be consisted of InstructionSeuqnece (iseq)
  (RubyVM::InstructionSeuqnece.of(code) should not return nil)
  If code is a tree of iseq, TracePoint is enabled on all of
  iseqs in a tree.

  Enabled tragetting TracePoints can not enabled again with
  and without target.

* vm_core.h (rb_iseq_t): introduce `rb_iseq_t::local_hooks`
  to store local hooks.
  `rb_iseq_t::aux::trace_events` is renamed to
  `global_trace_events` to contrast with `local_hooks`.

* vm_core.h (rb_hook_list_t): add `rb_hook_list_t::running`
  to represent how many Threads/Fibers are used this list.
  If this field is 0, nobody using this hooks and we can
  delete it.

  This is why we can remove code from cont.c.

* vm_core.h (rb_vm_t): because of above change, we can eliminate
  `rb_vm_t::trace_running` field.
  Also renamed from `rb_vm_t::event_hooks` to `global_hooks`.

* vm_core.h, vm.c (ruby_vm_event_enabled_global_flags): renamed
  from `ruby_vm_event_enabled_flags.

* vm_core.h, vm.c (ruby_vm_event_local_num): added to count
  enabled targetting TracePoints.

* vm_core.h, vm_trace.c (rb_exec_event_hooks): accepts
  hook list.

* vm_core.h (rb_vm_global_hooks): added for convinience.

* method.h (rb_method_bmethod_t): added to maintain Proc
  and `rb_hook_list_t` for bmethod (defined by define_method).

* prelude.rb (TracePoint#enable): extracet a keyword parameter
  (because it is easy than writing in C).
  It calls `TracePoint#__enable` internal method written in C.

* vm_insnhelper.c (vm_trace): check also iseq->local_hooks.

* vm.c (invoke_bmethod): check def->body.bmethod.hooks.

* vm.c (hook_before_rewind): check iseq->local_hooks
  and def->body.bmethod.hooks before rewind by exception.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66003 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-26 18:16:39 +00:00
nobu
16a642c331 Enable refinements at Object#respond_to?
[Feature #15327] [Fix GH-2020]

From: osyo-manga <manga.osyo@gmail.com>

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65920 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-22 08:29:02 +00:00
usa
67d87b192b Fix problem about notimplemented case
Re-revert r64340, and take care about notimplemented case.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64343 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-13 13:48:27 +00:00
kazu
ee05c56752 Revert "Support optional inherit argument for Module#method_defined?"
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64340 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-13 13:27:47 +00:00
svn
efd5a57481 * remove trailing spaces.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64338 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-13 12:42:04 +00:00
usa
bccb24a866 Support optional inherit argument for Module#method_defined?
Module has many introspection methods for methods and constants that
either return an array or return true or false for whether the method
or constant is defined. Most of these methods support an optional
argument that controls whether to consider inheritance.  Currently,
the following Module methods support such a argument:

* const_defined?
* constants
* instance_methods
* private_instance_methods
* protected_instance_methods
* public_instance_methods

and the following methods do not:

* method_defined?
* private_method_defined?
* protected_method_defined?
* public_method_defined?

This patch supports such an argument for the *method_defined?
methods.

While you can currently work around the lack of support via:

  mod.instance_methods(false).include?(:method_name)

This patch allows the simpler and more efficient:

  mod.method_defined?(:method_name, false)

One case where you want to exclude inheritance when checking
for a method definition is when you want to replace a method
that may already exist.  To avoid a verbose warning, you want
to remove the method only if it is already defined:

  remove_method(:foo) if method_defined?(:foo, false)
  define_method(:foo){}

You can't call remove_method without checking for the method
definition, as that can raise a NameError, and you don't want
to include inheritance because remove_method will still raise
a NameError if the method is defined by an ancestor and not
by the module itself.

[ruby-core:88140] [Feature #14944]

From: Jeremy Evans <code@jeremyevans.net>


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64337 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-13 12:42:03 +00:00
kazu
2ce807e895 Remove unnecessary assignment
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64212 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-07 12:00:54 +00:00
mame
ffb09d8e87 eval.c: rename "rb_frozen_class_p" to "rb_class_modify_check"
Just refactoring.  Despite its name, the function does NOT return a
boolean but raises an exception when the class given is frozen.
I don't think the new name "rb_class_modify_check" is the best, but
it follows the precedeint "rb_ary_modify_check", and is definitely
better than "*_p".

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64078 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-27 13:57:14 +00:00
k0kubun
ba8413c27c vm.c: simplify the implementation of r64031
because such inconsistency may result in the regression fixed in r64034.

vm_exec is not touched since renaming it may be controversial...

vm_args.c: ditto.
vm_eval.c: ditto.
vm_insnhelper.c: ditto.
vm_method.c: ditto.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64035 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-24 15:17:08 +00:00