Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 3 additions & 12 deletions gc/default/default.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,6 @@
# include <mach/mach_port.h>
#endif

#ifndef VM_CHECK_MODE
# define VM_CHECK_MODE RUBY_DEBUG
#endif

// From ractor_core.h
#ifndef RACTOR_CHECK_MODE
# define RACTOR_CHECK_MODE (VM_CHECK_MODE || RUBY_DEBUG) && (SIZEOF_UINT64_T == SIZEOF_VALUE)
#endif

#ifndef RUBY_DEBUG_LOG
# define RUBY_DEBUG_LOG(...)
#endif
Expand Down Expand Up @@ -691,10 +682,10 @@ typedef struct rb_objspace {
#define HEAP_PAGE_ALIGN_LOG 16
#endif

#if RACTOR_CHECK_MODE || GC_DEBUG
#if RB_GC_OBJ_HAS_SUFFIX || GC_DEBUG
struct rvalue_overhead {
# if RACTOR_CHECK_MODE
uint32_t _ractor_belonging_id;
# ifdef RB_GC_OBJ_HAS_SUFFIX
struct rb_gc_obj_suffix suffix;
# endif
# if GC_DEBUG
const char *file;
Expand Down
23 changes: 23 additions & 0 deletions gc/gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,32 @@
* first introduced for [Feature #20470].
*/
#include "ruby/ruby.h"
#include "ruby/assert.h"

#include "ruby/thread_native.h"

#ifndef VM_CHECK_MODE
# define VM_CHECK_MODE RUBY_DEBUG
#endif

// From ractor_core.h
#ifndef RACTOR_CHECK_MODE
# define RACTOR_CHECK_MODE (VM_CHECK_MODE || RUBY_DEBUG) && (SIZEOF_UINT64_T == SIZEOF_VALUE)
#endif

#if RACTOR_CHECK_MODE
void rb_ractor_setup_belonging(VALUE obj);

struct rb_gc_obj_suffix {
uint32_t _ractor_belonging_id;
};

# define RB_GC_OBJ_HAS_SUFFIX 1
# define RB_GC_OBJ_SUFFIX_SIZE (sizeof(struct rb_gc_obj_suffix))
#else
# define RB_GC_OBJ_SUFFIX_SIZE 0
#endif

struct rb_gc_vm_context {
rb_nativethread_lock_t lock;

Expand Down
11 changes: 6 additions & 5 deletions pathname.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,14 @@ path_root_p(VALUE self)
*
* Returns whether +self+ contains an absolute path:
*
* Pathname.new('/home').absolute? # => true
* Pathname.new('lib').absolute? # => false
* Pathname('/home').absolute? # => true
* Pathname('lib').absolute? # => false
*
* OS-dependent for some paths:
* The result is OS-dependent for some paths:
*
* Pathname('C:/').absolute? # => true # On Windows.
* Pathname('C:/').absolute? # => false # Elsewhere.
*
* Pathname.new('C:/').absolute? # => true # On Windows.
* Pathname.new('C:/').absolute? # => false # Elsewhere.
*/
static VALUE
path_absolute_p(VALUE self)
Expand Down
54 changes: 41 additions & 13 deletions pathname_builtin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1040,26 +1040,54 @@ def binwrite(...) File.binwrite(@path, ...) end
# See {File System Timestamps}[rdoc-ref:file/timestamps.md].
def atime() File.atime(@path) end

# :markup: markdown
#
# call-seq:
# birthtime -> new_time
#
# Returns a new Time object containing the create time of the entry
# represented by +self+:
#
# filepath = 't.tmp'
# pn = Pathname.new(filepath)
# pn.birthtime # Raises Errno::ENOENT: No such file or directory
# file = File.open(filepath, 'w')
# pn.birthtime # => 2026-04-14 16:14:47.494846 -0500
# file.birthtime # => 2026-04-14 16:14:47.494846 -0500
# file.write('foo')
# pn.birthtime # => 2026-04-14 16:14:47.494846 -0500
# file.close
# pn.birthtime # => 2026-04-14 16:14:47.494846 -0500
# File.delete(filepath)
# pn.birthtime # Raises Errno::ENOENT: No such file or directory
# ```ruby
# # Work in a temporary directory.
# Pathname.mktmpdir do |tmpdirpath|
# # A subdirectory therein, and its Pathname.
# dirpath = File.join(tmpdirpath, 'subdir')
# dir_pn = Pathname(dirpath)
# puts "Create directory; directory birthtime established."
# dir_pn.mkdir
# puts " Directory birthtime: #{dir_pn.birthtime}"
# sleep(1)
#
# # A file in the subdirectory, and its Pathname.
# filepath = File.join(dirpath, 't.txt')
# file_pn = Pathname(filepath)
# puts "Create file; file birthtime established; directory birthtime not updated."
# file_pn.write('foo')
# puts " File birthtime: #{file_pn.birthtime}"
# puts " Directory birthtime: #{dir_pn.birthtime}"
# sleep(1)
# puts "Write file; neither birthtime updated."
# file_pn.write('bar')
# puts " File birthtime: #{file_pn.birthtime}"
# puts " Directory birthtime: #{dir_pn.birthtime}"
# end
# ```
#
# See {File System Timestamps}[rdoc-ref:file/timestamps.md].
# Output:
#
# ```text
# Create directory; directory birthtime established.
# Directory birthtime: 2026-05-14 23:41:12 +0100
# Create file; file birthtime established; directory birthtime not updated.
# File birthtime: 2026-05-14 23:41:13 +0100
# Directory birthtime: 2026-05-14 23:41:12 +0100
# Write file; neither birthtime updated.
# File birthtime: 2026-05-14 23:41:13 +0100
# Directory birthtime: 2026-05-14 23:41:12 +0100
# ```
#
# See [File System Timestamps](rdoc-ref:file/timestamps.md).
def birthtime() File.birthtime(@path) end

# See <tt>File.ctime</tt>. Returns last (directory entry, not file) change time.
Expand Down
37 changes: 37 additions & 0 deletions test/ruby/test_refinement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,43 @@ def ===(other)
RUBY
end

def test_prohibit_super_in_refined_module_method
assert_separately([], <<-"end;")
bug22071 = '[ruby-core:125511] [Bug #22071]'
class BasicObject
def a; "B" end
end

module G
def a; "G" + super end
end

module F
include G
def a; "F" + super end
end

class A
def a; "A" + super end
end

class B < A
include F
end

module R
refine F do
def a; "R"+super end
end
end
using R

msg = "super in a method in a module that has been refined and that is called via super" +
" from a refinement method is not supported."
assert_raise(NoMethodError, msg, bug22071) { B.new.a }
end;
end

def test_refine_after_using
assert_separately([], <<-"end;")
bug8880 = '[ruby-core:57079] [Bug #8880]'
Expand Down
7 changes: 7 additions & 0 deletions vm_insnhelper.c
Original file line number Diff line number Diff line change
Expand Up @@ -5061,6 +5061,13 @@ vm_search_super_method(const rb_control_frame_t *reg_cfp, struct rb_call_data *c
cc = vm_cc_new(Qundef, NULL, vm_call_method_missing, cc_type_super);
RB_OBJ_WRITE(iseq, &cd->cc, cc);
}
else if (klass == rb_cBasicObject &&
RB_TYPE_P(me->defined_class, T_ICLASS) &&
RCLASS_INCLUDER(me->defined_class) == 0) {
rb_raise(rb_eNoMethodError,
"super in a method in a module that has been refined and that is called via super"
" from a refinement method is not supported.");
}
else {
cc = vm_search_method_fastpath(reg_cfp, cd, klass);
const rb_callable_method_entry_t *cached_cme = vm_cc_cme(cc);
Expand Down
2 changes: 0 additions & 2 deletions zjit/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,8 +492,6 @@ fn gen_function(cb: &mut CodeBlock, iseq: IseqPtr, version: IseqVersionRef, func
debug!("ZJIT: gen_function: Failed to compile insn: {insn_id} {insn}. Generating side-exit.");
gen_incr_counter(&mut asm, exit_counter_for_unhandled_hir_insn(&insn));
let reason = match insn {
Insn::ArrayMax { .. } => SideExitReason::UnhandledHIRArrayMax,
Insn::FixnumDiv { .. } => SideExitReason::UnhandledHIRFixnumDiv,
Insn::Throw { .. } => SideExitReason::UnhandledHIRThrow,
Insn::InvokeBuiltin { .. } => SideExitReason::UnhandledHIRInvokeBuiltin,
_ => SideExitReason::UnhandledHIRUnknown(insn_id),
Expand Down
2 changes: 0 additions & 2 deletions zjit/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,6 @@ pub enum SideExitReason {
UnhandledNewarraySend(vm_opt_newarray_send_type),
UnhandledDuparraySend(u64),
UnknownSpecialVariable(u64),
UnhandledHIRArrayMax,
UnhandledHIRFixnumDiv,
UnhandledHIRThrow,
UnhandledHIRInvokeBuiltin,
UnhandledHIRUnknown(InsnId),
Expand Down
2 changes: 0 additions & 2 deletions zjit/src/stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,8 +584,6 @@ pub fn side_exit_counter(reason: crate::hir::SideExitReason) -> Counter {
UnhandledCallType(Splat) => exit_unhandled_splat,
UnhandledCallType(Kwarg) => exit_unhandled_kwarg,
UnknownSpecialVariable(_) => exit_unknown_special_variable,
UnhandledHIRArrayMax => exit_unhandled_hir_insn,
UnhandledHIRFixnumDiv => exit_unhandled_hir_insn,
UnhandledHIRThrow => exit_unhandled_hir_insn,
UnhandledHIRInvokeBuiltin => exit_unhandled_hir_insn,
UnhandledHIRUnknown(_) => exit_unhandled_hir_insn,
Expand Down