diff --git a/compile.c b/compile.c
index a7308c66b1b50e..2ff207928a57e6 100644
--- a/compile.c
+++ b/compile.c
@@ -12680,7 +12680,7 @@ typedef uint32_t ibf_offset_t;
#define IBF_MAJOR_VERSION ISEQ_MAJOR_VERSION
#ifdef RUBY_DEVEL
-#define IBF_DEVEL_VERSION 7
+#define IBF_DEVEL_VERSION 8
#define IBF_MINOR_VERSION (ISEQ_MINOR_VERSION * 10000 + IBF_DEVEL_VERSION)
#else
#define IBF_MINOR_VERSION ISEQ_MINOR_VERSION
@@ -13774,7 +13774,6 @@ ibf_dump_iseq_each(struct ibf_dump *dump, const rb_iseq_t *iseq)
const struct rb_iseq_constant_body *body = ISEQ_BODY(iseq);
const VALUE location_pathobj_index = ibf_dump_object(dump, body->location.pathobj); /* TODO: freeze */
- const VALUE location_base_label_index = ibf_dump_object(dump, body->location.base_label);
const VALUE location_label_index = ibf_dump_object(dump, body->location.label);
#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
@@ -13856,7 +13855,6 @@ ibf_dump_iseq_each(struct ibf_dump *dump, const rb_iseq_t *iseq)
ibf_dump_write_small_value(dump, IBF_BODY_OFFSET(param_opt_table_offset));
ibf_dump_write_small_value(dump, param_keyword_offset);
ibf_dump_write_small_value(dump, location_pathobj_index);
- ibf_dump_write_small_value(dump, location_base_label_index);
ibf_dump_write_small_value(dump, location_label_index);
ibf_dump_write_small_value(dump, body->location.first_lineno);
ibf_dump_write_small_value(dump, body->location.node_id);
@@ -13972,7 +13970,6 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset)
const ibf_offset_t param_opt_table_offset = (ibf_offset_t)IBF_BODY_OFFSET(ibf_load_small_value(load, &reading_pos));
const ibf_offset_t param_keyword_offset = (ibf_offset_t)ibf_load_small_value(load, &reading_pos);
const VALUE location_pathobj_index = ibf_load_small_value(load, &reading_pos);
- const VALUE location_base_label_index = ibf_load_small_value(load, &reading_pos);
const VALUE location_label_index = ibf_load_small_value(load, &reading_pos);
const int location_first_lineno = (int)ibf_load_small_value(load, &reading_pos);
const int location_node_id = (int)ibf_load_small_value(load, &reading_pos);
@@ -14137,7 +14134,6 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset)
load->current_buffer = &load->global_buffer;
#endif
- RB_OBJ_WRITE(iseq, &load_body->location.base_label, ibf_load_location_str(load, location_base_label_index));
RB_OBJ_WRITE(iseq, &load_body->location.label, ibf_load_location_str(load, location_label_index));
#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
diff --git a/depend b/depend
index 166d1266703288..a18eebe3fa96b1 100644
--- a/depend
+++ b/depend
@@ -36,7 +36,7 @@
# mkdepend: depends vmtc.inc => {$(VPATH)}vmtc.inc
# mkdepend: undef parse.y => RIPPER
-.deps/depend update-dependencies: $(srcdir)/depend \
+.deps/depend update-dependencies: $(REVISION_H) $(srcdir)/depend \
$(srcdir)/tool/mkdepend.rb \
$(srcdir)/lib/mkmf/depend.rb
$(BASERUBY) "$(srcdir)/tool/mkdepend.rb" --root="$(srcdir)" \
diff --git a/doc/file/filesystem_modes.md b/doc/file/filesystem_modes.md
index 33b69c386119e7..078853591998ff 100644
--- a/doc/file/filesystem_modes.md
+++ b/doc/file/filesystem_modes.md
@@ -50,13 +50,17 @@ Dir.rmdir(dirpath)
You can use one of these methods to change the [permissions][permissions]
and [special bits][special bits] (but not the [file type][file type]):
+- File#chmod.
- File::chmod.
+- File::lchmod (does not follow symbolic links).
+- FileUtils#chmod.
+- FileUtils#chmod_R.
- FileUtils::chmod.
- FileUtils::chmod_R.
-- File#chmod.
- Pathname#chmod.
-- FileUtils#chmod.
-- FileUtils#chmod_R.
+- Pathname#lchmod (does not follow symbolic links).
+
+The actual effects of these methods is filesystem-dependent.
## Permissions
diff --git a/file.c b/file.c
index 6c46b908440008..995111e89d88a7 100644
--- a/file.c
+++ b/file.c
@@ -2946,26 +2946,28 @@ chmod_internal(const char *path, void *mode)
/*
* call-seq:
- * File.chmod(mode, *paths) -> integer
+ * File.chmod(mode, *paths) -> integer
*
- * Changes the mode (i.e., permissions) of the entries of each the given +paths+;
- * see {File Permissions}[rdoc-ref:File@File+Permissions].
- * Returns the count of the given +paths+:
+ * Changes the modes of each of the entries at each the given +paths+;
+ * returns the count of the given +paths+.
+ * See {Filesystem Modes}[rdoc-ref:file/filesystem_modes.md]
+ * and especially {Setting a Mode}[rdoc-ref:file/filesystem_modes.md@Setting+a+Mode].
*
- * filepath = 't.tmp'
- * File.write(filepath, 'foo')
- * dirpath = 'tempdir'
- * Dir.mkdir(dirpath)
- * File::Stat.new(filepath).mode.to_s(8) # => "100664"
- * File::Stat.new(dirpath).mode.to_s(8) # => "40775"
- * File.chmod(0775, filepath, dirpath) # => 2
- * File::Stat.new(filepath).mode.to_s(8) # => "100775"
- * File::Stat.new(dirpath).mode.to_s(8) # => "40775"
- * File.chmod(0664, filepath, dirpath) # => 2
- * File::Stat.new(filepath).mode.to_s(8) # => "100664"
- * File::Stat.new(dirpath).mode.to_s(8) # => "40664"
- * File.delete(filepath)
- * Dir.rmdir(dirpath)
+ * These examples use
+ * a {helper method}[rdoc-ref:file/filesystem_modes.md@Helper+Method], +mode+,
+ * that displays a mode both in octal digits and in characters:
+ *
+ * dirpath = 'doc/foo'
+ * filepath = File.join(dirpath, 't.tmp')
+ * Dir.mkdir(dirpath) # Create directory.
+ * mode(dirpath) # => "040775 drwxrwxr-x"
+ * File.write(filepath, 'bar') # Create file.
+ * mode(filepath) # => "100664 -rw-rw-r--"
+ * File.chmod(0755, filepath) # Change file mode.
+ * mode(filepath) # => "100755 -rwxr-xr-x"
+ * File.chmod(0664, dirpath) # Change directory mode.
+ * mode(dirpath) # => "040664 drw-rw-r--"
+ * FileUtils.rm_rf(dirpath) # Clean up.
*
*/
@@ -3005,15 +3007,25 @@ rb_fchmod(struct rb_io* io, mode_t mode)
/*
* call-seq:
- * file.chmod(mode_int) -> 0
+ * chmod(mode) -> 0
+ *
+ * Changes the mode of +self+; returns '0'.
+ * See {Filesystem Modes}[rdoc-ref:file/filesystem_modes.md]
+ * and especially {Setting a Mode}[rdoc-ref:file/filesystem_modes.md@Setting+a+Mode].
*
- * Changes permission bits on file to the bit pattern
- * represented by mode_int. Actual effects are platform
- * dependent; on Unix systems, see chmod(2) for details.
- * Follows symbolic links. Also see File#lchmod.
+ * These examples use
+ * a {helper method}[rdoc-ref:file/filesystem_modes.md@Helper+Method], +mode+,
+ * that displays a mode both in octal digits and in characters:
+ *
+ * filepath = 'doc/t.tmp'
+ * File.write(filepath, 'foo')
+ * file = File.new(filepath)
+ * mode(filepath) # => "100664 -rw-rw-r--"
+ * file.chmod(0775)
+ * mode(filepath) # => "100775 -rwxrwxr-x"
+ * file.close
+ * File.delete(filepath)
*
- * f = File.new("out", "w");
- * f.chmod(0644) #=> 0
*/
static VALUE
diff --git a/iseq.c b/iseq.c
index 4cffe90f4d56a9..d88ade75866c0e 100644
--- a/iseq.c
+++ b/iseq.c
@@ -415,7 +415,6 @@ rb_iseq_mark_and_move(rb_iseq_t *iseq, bool reference_updating)
struct rb_iseq_variable *v = ISEQ_VARIABLE(iseq);
if (v) rb_gc_mark_and_move(&v->script_lines);
rb_gc_mark_and_move(&body->location.label);
- rb_gc_mark_and_move(&body->location.base_label);
rb_gc_mark_and_move(&body->location.pathobj);
if (body->local_iseq) rb_gc_mark_and_move_ptr(&body->local_iseq);
if (body->parent_iseq) rb_gc_mark_and_move_ptr(&body->parent_iseq);
@@ -711,7 +710,6 @@ iseq_location_setup(rb_iseq_t *iseq, VALUE name, VALUE path, VALUE realpath, int
rb_iseq_pathobj_set(iseq, path, realpath);
RB_OBJ_WRITE(iseq, &loc->label, name);
- RB_OBJ_WRITE(iseq, &loc->base_label, name);
loc->first_lineno = first_lineno;
if (ISEQ_BODY(iseq)->local_iseq == iseq && rb_streql_lit(name, "initialize")) {
@@ -803,9 +801,6 @@ prepare_iseq_build(rb_iseq_t *iseq,
name = rb_fstring(name);
iseq_location_setup(iseq, name, path, realpath, first_lineno, code_location, node_id);
- if (iseq != body->local_iseq) {
- RB_OBJ_WRITE(iseq, &body->location.base_label, ISEQ_BODY(body->local_iseq)->location.label);
- }
ISEQ_ORIGINAL_ISEQ_CLEAR(iseq);
if (body->variable) {
body->variable->flip_count = 0;
@@ -1619,7 +1614,15 @@ rb_iseq_label(const rb_iseq_t *iseq)
VALUE
rb_iseq_base_label(const rb_iseq_t *iseq)
{
- return ISEQ_BODY(iseq)->location.base_label;
+ const struct rb_iseq_constant_body *body = ISEQ_BODY(iseq);
+ const rb_iseq_t *local_iseq = body->local_iseq;
+
+ if (local_iseq == NULL || local_iseq == iseq) {
+ return body->location.label;
+ }
+ else {
+ return ISEQ_BODY(rb_iseq_check(local_iseq))->location.label;
+ }
}
VALUE
@@ -1634,7 +1637,7 @@ rb_iseq_method_name(const rb_iseq_t *iseq)
struct rb_iseq_constant_body *const body = ISEQ_BODY(ISEQ_BODY(iseq)->local_iseq);
if (body->type == ISEQ_TYPE_METHOD) {
- return body->location.base_label;
+ return body->location.label;
}
else {
return Qnil;
diff --git a/pathname_builtin.rb b/pathname_builtin.rb
index 6b8108ce0871cc..e538408ff62bc6 100644
--- a/pathname_builtin.rb
+++ b/pathname_builtin.rb
@@ -1503,31 +1503,28 @@ def mtime() File.mtime(@path) end
# call-seq:
# chmod(mode) -> 1
#
- # Changes the mode (i.e., permissions) of the entry represented by `self`;
- # see {File Permissions}[rdoc-ref:File@File+Permissions]:
- #
- # ```ruby
- # # Pathname for a (non-existent) directory.
- # dir_pn = Pathname('doc/foo') # => #
- # # Create the directory and fetch its mode.
- # dir_pn.mkdir
- # dir_pn.stat.mode.to_s(8) # => "40775"
- # # Change the directory mode and fetch the new mode.
- # dir_pn.chmod(0777)
- # dir_pn.stat.mode.to_s(8) # => "40777"
- #
- # # Pathname for a (non-existent) file in the directory.
- # file_pn = dir_pn.join('t.tmp') # => #
- # # Create the file and fetch its mode.
- # file_pn.write('foo')
- # file_pn.stat.mode.to_s(8) # => "100664"
- # # Change the file mode and fetch its new mode.
- # file_pn.chmod(0777)
- # file_pn.stat.mode.to_s(8) # => "100777"
- #
- # # Clean up.
- # file_pn.delete
- # dir_pn.rmdir
+ # Changes the mode of the entry at the path in `self`; returns `1`.
+ # See {Filesystem Modes}[rdoc-ref:file/filesystem_modes.md]
+ # and especially {Setting a Mode}[rdoc-ref:file/filesystem_modes.md@Setting+a+Mode].
+ #
+ # These examples use
+ # a {helper method}[rdoc-ref:file/filesystem_modes.md@Helper+Method], `mode`,
+ # that displays a mode both in octal digits and in characters:
+ #
+ # ```ruby
+ # dirpath = 'doc/foo'
+ # dir_pn = Pathname(dirpath)
+ # dir_pn.mkdir # Create directory.
+ # mode(dirpath) # => "040775 drwxrwxr-x"
+ # filepath = File.join(dirpath, 't.tmp')
+ # file_pn = Pathname(filepath)
+ # file_pn.write('bar') # Create file.
+ # mode(filepath) # => "100664 -rw-rw-r--"
+ # file_pn.chmod(0755) # Change file mode.
+ # mode(filepath) # => "100755 -rwxr-xr-x"
+ # dir_pn.chmod(0644) # Change directory mode.
+ # mode(dirpath) # => "040644 drw-r--r--"
+ # dir_pn.rmtree # Clean up.
# ```
#
def chmod(mode) File.chmod(mode, @path) end
diff --git a/vm_backtrace.c b/vm_backtrace.c
index f13d4273179785..19bcd7dc72a0cc 100644
--- a/vm_backtrace.c
+++ b/vm_backtrace.c
@@ -374,7 +374,7 @@ location_base_label(rb_backtrace_location_t *loc)
return rb_id2str(loc->cme->def->original_id);
}
- return ISEQ_BODY(loc->iseq)->location.base_label;
+ return rb_iseq_base_label(loc->iseq);
}
/*
diff --git a/vm_core.h b/vm_core.h
index 2c416859573d63..fc64d278c65b50 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -338,7 +338,6 @@ struct rb_execution_context_struct;
typedef struct rb_iseq_location_struct {
VALUE pathobj; /* String (path) or Array [path, realpath]. Frozen. */
- VALUE base_label; /* String */
VALUE label; /* String */
int first_lineno;
int node_id;
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index bc8b327e35b002..3a0b7324046e59 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -3160,7 +3160,7 @@ warn_unused_block(const rb_callable_method_entry_t *cme, const rb_iseq_t *iseq,
}
else if (RTEST(ruby_verbose) || strict_unused_block) {
VALUE m_loc = rb_method_entry_location((const rb_method_entry_t *)cme);
- VALUE name = rb_gen_method_name(cme->defined_class, ISEQ_BODY(iseq)->location.base_label);
+ VALUE name = rb_gen_method_name(cme->defined_class, rb_iseq_base_label(iseq));
if (!NIL_P(m_loc)) {
rb_warn("the block passed to '%"PRIsVALUE"' defined at %"PRIsVALUE":%"PRIsVALUE" may be ignored",
diff --git a/zjit/src/cruby_bindings.inc.rs b/zjit/src/cruby_bindings.inc.rs
index 9e2946ea4030e6..0821ed934d5ac1 100644
--- a/zjit/src/cruby_bindings.inc.rs
+++ b/zjit/src/cruby_bindings.inc.rs
@@ -619,7 +619,6 @@ pub struct iseq_inline_storage_entry {
#[repr(C)]
pub struct rb_iseq_location_struct {
pub pathobj: VALUE,
- pub base_label: VALUE,
pub label: VALUE,
pub first_lineno: ::std::os::raw::c_int,
pub node_id: ::std::os::raw::c_int,
@@ -2099,7 +2098,7 @@ pub struct zjit_jit_frame {
pub stack: __IncompleteArrayField,
}
pub const ISEQ_BODY_OFFSET_PARAM: zjit_struct_offsets = 16;
-pub const ISEQ_BODY_OFFSET_OUTER_VARIABLES: zjit_struct_offsets = 248;
+pub const ISEQ_BODY_OFFSET_OUTER_VARIABLES: zjit_struct_offsets = 240;
pub const RUBY_OFFSET_THREAD_RACTOR: zjit_struct_offsets = 24;
pub type zjit_struct_offsets = u32;
#[repr(C)]