662 Commits
Author SHA1 Message Date
Mike Dalessio b952b6f099 Fix UnboundMethod#== for methods from included/extended modules [Backport #21873]
Method#unbind clones the method entry, preserving its defined_class.
For methods mixed in via include/extend, defined_class is an ICLASS,
causing UnboundMethod#== to return false when comparing against the
same method obtained via Module#instance_method.

Resolve ICLASS defined_class in method_eq.

[Bug #21873]
2026-02-12 15:05:36 +09:00
nagachika e39a0a19c0 merge revision(s) ce849d565b, acb29f7fa1: [Backport #21402]
ruby2_keywords warnings: Quote non-UTF8 method names fully

	It used to quote only part of the method name because NUL byte in
	the method terminates the C string:

	```
	(irb)> "abcdef".encode("UTF-16LE").bytes
	=> [97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0]
	```

	```
	expected: /abcdef/
	actual: warning: Skipping set of ruby2_keywords flag for a (method not defined in Ruby)\n".
	```

	Do not respect ruby2_keywords on method/proc with post arguments

	Previously, ruby2_keywords could be used on a method or proc with
	post arguments, but I don't think the behavior is desired:

	```ruby
	def a(*c, **kw) [c, kw] end
	def b(*a, b) a(*a, b) end
	ruby2_keywords(:b)

	b({foo: 1}, bar: 1)
	```

	This changes ruby2_keywords to emit a warning and not set the
	flag on a method/proc with post arguments.

	While here, fix the ruby2_keywords specs for warnings, since they
	weren't testing what they should be testing.  They all warned
	because the method didn't accept a rest argument, not because it
	accepted a keyword or keyword rest argument.
2025-09-14 12:47:12 +09:00
nagachika d5c8fd2043 merge revision(s) f6cbf499bc: [Backport #21354]
Fix Symbol#to_proc (rb_sym_to_proc) to be ractor safe

	In non-main ractors, don't use `sym_proc_cache`. It is not thread-safe
	to add to this array without a lock and also it leaks procs from one
	ractor to another. Instead, we create a new proc each time. If this
	results in poor performance we can come up with a solution later.

	Fixes [Bug #21354]
2025-06-14 11:39:08 +09:00
Takashi Kokubun 299455be99 merge revision(s) 92dd9734a9: [Backport #20950]
Fix use-after-free in ep in Proc#dup for ifunc procs

	[Bug #20950]

	ifunc proc has the ep allocated in the cfunc_proc_t which is the data of
	the TypedData object. If an ifunc proc is duplicated, the ep points to
	the ep of the source object. If the source object is freed, then the ep
	of the duplicated object now points to a freed memory region. If we try
	to use the ep we could crash.

	For example, the following script crashes:

	    p = { a: 1 }.to_proc
	    100.times do
	      p = p.dup
	      GC.start
	      p.call
	    rescue ArgumentError
	    end

	This commit changes ifunc proc to also duplicate the ep when it is duplicated.
2025-01-14 17:54:19 -08:00
Takashi Kokubun 6db39f4677 merge revision(s) 29c480dd6f: [Backport #20853]
[Bug #20853] Fix Proc#hash to not change after compaction

	The hash value of a Proc must remain constant after a compaction, otherwise
	it may not work as the key in a hash table.
2024-11-04 14:43:39 -08:00
Takashi Kokubun a24f19742b merge revision(s) 58918788ab: [Backport #20342]
[Bug #20342] Consider wrapped load in `main` methods
2024-05-29 15:40:49 -07:00
NARUSE, YuiandÉtienne Barrié a63e979853 merge revision(s) d19d683a354530a27b4cbb049223f8dc70c75849,de1a586ecc2ee7f465f0c0a69291054136a3a819: [Backport #20250] (#10308)
rb_obj_setup: do not copy RUBY_FL_SEEN_OBJ_ID

	[Bug #20250]

	We're seting up a new instance, so it never had an associated
	object_id.

	proc.c: get rid of `CLONESETUP`
	MIME-Version: 1.0
	Content-Type: text/plain; charset=UTF-8
	Content-Transfer-Encoding: 8bit

	[Bug #20253]

	All the way down to Ruby 1.9, `Proc`, `Method`, `UnboundMethod`
	and `Binding` always had their own specific clone and dup routine.

	This caused various discrepancies with how other objects behave
	on `dup` and `clone. [Bug #20250], [Bug #20253].

	This commit get rid of `CLONESETUP` and use the the same codepath
	as all other types, so ensure consistency.

	NB: It's still not accepting the `freeze` keyword argument on `clone`.

	Co-Authored-By: Étienne Barrié <etienne.barrie@gmail.com>
2024-03-21 01:45:01 +00:00
Alan Wu 9f77eb1f5a Remove unused macros 2023-12-12 17:24:17 -05:00
Peter Zhu ed25f0bd5a Make env_clone compaction safe
The original order of events is:

1. Allocate new_body.
2. Peform memcpy into new_body.
3. Create new_env using new_body.

However, if GC compaction runs during step 3, then new_env would not
have yet been created and objects on new_body could move but it would
not be reference updated.

This commit changes the order of the last two events.
2023-12-05 08:42:25 -05:00
Jean Boussier b4f551686b Get rid of useless dsize functions
If we always return 0, we might as well not define
the function at all.
2023-11-21 15:15:03 +01:00
Jean Boussier ffb1eb37e7 proc.c: Make Method and UnboundMethod embded
Avoid some needless malloc churn

```
compare-ruby: ruby 3.3.0dev (2023-11-20T02:02:55Z master 701b0650de) [arm64-darwin22]
last_commit=[ruby/prism] feat: add encoding for IBM865 (https://github.com/ruby/prism/pull/1884)
built-ruby: ruby 3.3.0dev (2023-11-20T16:23:07Z embedded-methods e35284bfaa) [arm64-darwin22]
warming up..

|                         |compare-ruby|built-ruby|
|:------------------------|-----------:|---------:|
|allocate_method          |      8.413M|   12.333M|
|                         |           -|     1.47x|
|allocate_unbound_method  |      8.083M|   11.607M|
|                         |           -|     1.44x|
```

```
prelude: |
  class SomeClass
    def foo
    end
  end
  some_object = SomeClass.new
benchmark:
  allocate_method: some_object.method(:foo)
  allocate_unbound_method: SomeClass.instance_method(:foo)
```
2023-11-20 18:04:13 +01:00
Nobuyoshi Nakada 1507118f0b [Feature #19362] Call #initialize_dup hook at Proc#dup 2023-10-26 17:28:50 +09:00
Alan WuandTakashi Kokubun 39ee3e22bd Make Kernel#lambda raise when given non-literal block
Previously, Kernel#lambda returned a non-lambda proc when given a
non-literal block and issued a warning under the `:deprecated` category.
With this change, Kernel#lambda will always return a lambda proc, if it
returns without raising.

Due to interactions with block passing optimizations, we previously had
two separate code paths for detecting whether Kernel#lambda got a
literal block. This change allows us to remove one path, the hack done
with rb_control_frame_t::block_code introduced in 85a337f for supporting
situations where Kernel#lambda returned a non-lambda proc.

[Feature #19777]

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-09-12 11:25:07 -04:00
Jeremy Evans 786a864900 Make {Nil,True,False}Class#singleton_method always raise NameError
{Nil,True,False}Class#singleton_methods always returns [] indicating
that there are no singleton methods defined, so #singleton_method
should be consistent with that.

Fixes [Bug #11064]
2023-07-26 07:27:15 -07:00
Alan Wu 5c219c1b7f proc.c: Remove unused parameter [ci skip] 2023-07-20 10:53:31 -04:00
Matt Valentine-House d426343418 Store object age in a bitmap
Closes [Feature #19729]

Previously 2 bits of the flags on each RVALUE are reserved to store the
number of GC cycles that each object has survived. This commit
introduces a new bit array on the heap page, called age_bits, to store
that information instead.

This patch still reserves one of the age bits in the flags (the old
FL_PROMOTED0 bit, now renamed FL_PROMOTED).

This is set to 0 for young objects and 1 for old objects, and is used as
a performance optimisation for the write barrier. Fetching the age_bits
from the heap page and doing the required math to calculate if the
object was old or not would slow down the write barrier. So we keep this
bit synced in the flags for fast access.
2023-07-13 09:21:36 +01:00
Takashi Kokubun 233ddfac54 Stop exporting symbols for MJIT 2023-03-06 21:59:23 -08:00
zverok 0258e92e43 [DOC] Improve Kernel#binding docs
* Add links to Binding class
* Make examples practical
* Extend possible usages description
2023-02-19 22:32:52 +02:00
Jean Boussier 7413079dae Encapsulate RCLASS_ATTACHED_OBJECT
Right now the attached object is stored as an instance variable
and all the call sites that either get or set it have to know how it's
stored.

It's preferable to hide this implementation detail behind accessors
so that it is easier to change how it's stored.
2023-02-15 15:24:22 +01:00
Koichi Sasada be94808282 use correct svar even if env is escaped
This patch is follo-up of 0a82bfe.
Without this patch, if env is escaped (Proc'ed), strange svar
can be touched.

This patch tracks escaped env and use it.
2023-02-10 17:55:25 +09:00
Matt Valentine-House 72aba64fff Merge gc.h and internal/gc.h
[Feature #19425]
2023-02-09 10:32:29 -05:00
Peter Zhu 046807102f Use rb_gc_mark_and_move for method objects 2023-02-07 08:39:48 -05:00
Peter Zhu df2e36aeeb Use rb_gc_mark_and_move for proc and binding
Also makes VM_ENV_ENVVAL movable.
2023-02-07 08:39:48 -05:00
Jean Boussier a8000d06cc Mark "method" objects as protected by write barrier
All its reference are set with RB_OBJ_WRITE, so they
can be marked as WB protected.
2023-02-03 23:31:23 +01:00
Koichi SasadaandTakashi Kokubun 0a82bfe5e1 use correct svar (#7225)
* use correct svar

Without this patch, svar location is used "nearest Ruby frame".
It is almost correct but it doesn't correct when the `each` method
is written in Ruby.

```ruby
class C
  include Enumerable
  def each
    %w(bar baz).each{|e| yield e}
  end
end

C.new.grep(/(b.)/){|e| p [$1, e]}
```

This patch fix this issue by traversing ifunc's cfp.

Note that if cfp doesn't specify this Thread's cfp stack, reserved
svar location (`ec->root_svar`) is used.

* make yjit-bindgen

---------

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-02-01 16:13:19 -08:00
zverok 64cdf1936a Docs: Separate documentation for UnboundMethod#== 2022-12-23 18:09:49 +02:00
Koichi Sasada 59e389af28 UnboundMethod only refer defined_class
UnboundMethod records caller's class, like `D` or `E` on the
following case:

```ruby
class C
  def foo = :foo
end

class D < C
end

class E < C
end

d = D.instance_method(:foo)
e = E.instance_method(:foo)
```

But `d` and `e` only refers `C#foo` so that UnboundMethod doesn't
record `D` or `E`. This behavior changes the following methods:

* `UnboundMethod#inspect` (doesn't show caller's class)
* `UnboundMethod#==` (`d == e` for example)

fix https://bugs.ruby-lang.org/issues/18798
2022-12-03 08:53:12 +09:00
S-H-GAMELINKS 1f4f6c9832 Using UNDEF_P macro 2022-11-16 18:58:33 +09:00
Peter Zhu 93f364d65e Use RTEST to to check return value
rb_obj_is_kind_of returns a Ruby Qtrue or Qfalse. We should use RTEST
rather than assuming that Qfalse is 0.
2022-11-04 09:02:58 -04:00
Alexander MomchilovandMichael Herold 76a6c5d6d1 Remove unnecessary branch in UnboundMethod#bind
Co-authored-by: Michael Herold <michael.herold@shopify.com>
2022-11-04 08:57:01 -04:00
Benoit Daloze b91f685a26 Mark struct METHOD->owner for the GC
* Fixes https://github.com/ruby/ruby/commit/6b7d32a5e5
* See [Bug #18729]
2022-10-03 12:03:46 +02:00
Benoit Daloze aa490f9442 Reduce diff to proc.c @ b0b9f7201a
* So it's easy to review https://github.com/ruby/ruby/pull/6242 +
  https://github.com/ruby/ruby/pull/6467 and there are less changes
  overall.
2022-09-29 15:48:35 +02:00
Benoit Daloze 6b7d32a5e5 Resolve zsuper method during lookup but preserve owner separately
* See https://bugs.ruby-lang.org/issues/18729#note-34
* See [Bug #18729]
2022-09-29 15:48:35 +02:00
Benoit Daloze 94cea3e4d0 Fix {Method,UnboundMethod}#super_method for zsuper methods
* We need to resolve the zsuper method first, and then look the super
  method of that.
2022-09-29 15:48:35 +02:00
Samuel Williams 22af2e9084 Rework vm_core to use int first_lineno struct member. 2022-09-26 00:41:16 +13:00
S-H-GAMELINKS 205c252ec7 Reuse rb_method_call_kw function 2022-09-25 11:11:06 +13:00
Nobuyoshi Nakada 92d2476208 Adjust styles [ci skip] 2022-09-02 14:49:42 +09:00
Benoit Daloze 209631a45f Consider resolved-through-zsuper methods equal for compatibility
* Fixes https://bugs.ruby-lang.org/issues/18751
2022-08-20 13:44:00 +02:00
Jeremy EvansandBenoit Daloze 8212aab81a Make Object#method and Module#instance_method not skip ZSUPER methods
Based on https://github.com/jeremyevans/ruby/commit/c95e7e5329140f640b6497905485761f3336d967

Among other things, this fixes calling visibility methods (public?,
protected?, and private?) on them.  It also fixes #owner to show the
class the zsuper method entry is defined in, instead of the original
class it references.

For some backwards compatibility, adjust #parameters and #source_location,
to show the parameters and source location of the method originally
defined. Also have the parameters and source location still be shown
by #inspect.

Clarify documentation of {Method,UnboundMethod}#owner.

Add tests based on the description of https://bugs.ruby-lang.org/issues/18435
and based on https://github.com/ruby/ruby/pull/5356#issuecomment-1005298809

Fixes [Bug #18435] [Bug #18729]

Co-authored-by: Benoit Daloze <eregontp@gmail.com>
2022-08-20 13:44:00 +02:00
Penelope Phippen e49db0f760 Do not clone method entries when bind_call is used
I noticed that this site unconditionally clones the method entry, which
means that `bind_call` always allocates a `T_IMEMO`. While this clone
is necessary for `bind`, it is not necessary for `bind_call`.

I work at Stripe, and the sorbet_runtime gem uses bind call as part
of it's [call validation](https://github.com/sorbet/sorbet/blob/master/gems/sorbet-runtime/lib/types/private/methods/call_validation.rb#L157)
so this can save us a lot of allocations.

This patch adds a `clone` parameter to `convert_umethod_to_method_components`,
which then controls whether or not we do this cloning. This patch passed
Stripe CI and works in our QA environment. I reviewed it with @tenderlove
to talk about correctness also.
2022-08-15 15:41:35 -07:00
Jeremy Evans ff42e2359b Revert "Add {Method,UnboundMethod}#{public?,private?,protected?}"
This reverts commit 2727815068 and
58dc8bf8f1.

Visibility is an attribute of the method entry in a class, not an
attribute of the Method object.

Fixes [#18729]
Fixes [#18751]
Fixes [#18435]
2022-08-10 13:02:52 -07:00
Peter Zhu efb91ff19b Rename rb_ary_tmp_new to rb_ary_hidden_new
rb_ary_tmp_new suggests that the array is temporary in some way, but
that's not true, it just creates an array that's hidden and not on the
transient heap. This commit renames it to rb_ary_hidden_new.
2022-07-26 09:12:09 -04:00
Takashi Kokubun 5b21e94beb Expand tabs [ci skip]
[Misc #18891]
2022-07-21 09:42:04 -07:00
S.H 554befbf27 Reuse rb_proc_arity 2022-04-24 14:06:45 -07:00
Nobuyoshi Nakada 5d45afdbbf [DOC] Move the documentations of moved Symbol methods 2022-04-14 11:17:37 +09:00
Kazuhiro NISHIYAMA 8da0b68a62 Fix a typo [ci skip] 2022-04-06 11:59:35 +09:00
Jeremy Evans 173a6b6a80 Make define_singleton_method always define a public method
In very unlikely cases, it could previously define a non-public method
starting in Ruby 2.1.

Fixes [Bug #18561]
2022-03-29 12:10:13 -07:00
Peter Zhu 5f10bd634f Add ISEQ_BODY macro
Use ISEQ_BODY macro to get the rb_iseq_constant_body of the ISeq. Using
this macro will make it easier for us to change the allocation strategy
of rb_iseq_constant_body when using Variable Width Allocation.
2022-03-24 10:03:51 -04:00
Jeremy Evans 634e0a97eb Encourage arity argument in Proc#curry documentation for procs with variable arguments
This uses similar language to that used in Method#curry.
2022-03-17 20:34:13 -07:00
Jeremy Evans b6804d62f8 Make Proc#parameters support lambda keyword for returning parameters as if lambda
This makes it easier to use Proc#parameters to build wrappers.

Implements [Feature #15357]
2022-03-17 11:52:02 -07:00