summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/check_misc.yml6
-rw-r--r--compile.c3
-rw-r--r--gc.c1
-rw-r--r--hash.c1
-rw-r--r--io_buffer.c8
-rw-r--r--proc.c3
-rw-r--r--re.c3
-rw-r--r--test/ruby/test_io_buffer.rb10
-rw-r--r--test/ruby/test_zjit.rb14
-rw-r--r--thread.c3
-rwxr-xr-x[-rw-r--r--]tool/auto-style.rb21
-rw-r--r--vm.c3
-rw-r--r--zjit/src/codegen.rs12
-rw-r--r--zjit/src/hir.rs18
14 files changed, 85 insertions, 21 deletions
diff --git a/.github/workflows/check_misc.yml b/.github/workflows/check_misc.yml
index 543c54a3c9..2d73e1771a 100644
--- a/.github/workflows/check_misc.yml
+++ b/.github/workflows/check_misc.yml
@@ -37,10 +37,10 @@ jobs:
GIT_AUTHOR_NAME: git
GIT_COMMITTER_NAME: git
- GITHUB_OLD_SHA: ${{ startsWith(github.event_name, 'pull') && github.event.pull_request.base.sha || github.event.before }}
- GITHUB_NEW_SHA: ${{ startsWith(github.event_name, 'pull') && github.event.pull_request.merge_commit_sha || github.event.after }}
+ GITHUB_OLD_SHA: ${{ github.event.pull_request.base.sha }}
+ GITHUB_NEW_SHA: ${{ github.event.pull_request.merge_commit_sha }}
PUSH_REF: ${{ github.ref == 'refs/heads/master' && github.ref || '' }}
- if: ${{ github.repository == 'ruby/ruby' }}
+ if: ${{ github.repository == 'ruby/ruby' && startsWith(github.event_name, 'pull') }}
- name: Check if C-sources are US-ASCII
run: |
diff --git a/compile.c b/compile.c
index cbde124516..6bcfcd3398 100644
--- a/compile.c
+++ b/compile.c
@@ -13384,7 +13384,8 @@ outer_variable_cmp(const void *a, const void *b, void *arg)
if (!ap->name) {
return -1;
- } else if (!bp->name) {
+ }
+ else if (!bp->name) {
return 1;
}
diff --git a/gc.c b/gc.c
index e920348a12..f0189294bd 100644
--- a/gc.c
+++ b/gc.c
@@ -3060,7 +3060,6 @@ rb_gc_mark_roots(void *objspace, const char **categoryp)
MARK_CHECKPOINT("vm");
rb_vm_mark(vm);
- if (vm->self) gc_mark_internal(vm->self);
MARK_CHECKPOINT("end_proc");
rb_mark_end_proc();
diff --git a/hash.c b/hash.c
index be26e0eb3f..379dac814b 100644
--- a/hash.c
+++ b/hash.c
@@ -3872,7 +3872,6 @@ rb_hash_values(VALUE hash)
}
rb_ary_set_len(values, size);
}
-
else {
rb_hash_foreach(hash, values_i, values);
}
diff --git a/io_buffer.c b/io_buffer.c
index 40c12ef5c1..190b67d8ac 100644
--- a/io_buffer.c
+++ b/io_buffer.c
@@ -496,7 +496,9 @@ io_buffer_for_yield_instance(VALUE _arguments)
arguments->instance = io_buffer_for_make_instance(arguments->klass, arguments->string, arguments->flags);
- rb_str_locktmp(arguments->string);
+ if (!RB_OBJ_FROZEN(arguments->string)) {
+ rb_str_locktmp(arguments->string);
+ }
return rb_yield(arguments->instance);
}
@@ -510,7 +512,9 @@ io_buffer_for_yield_instance_ensure(VALUE _arguments)
rb_io_buffer_free(arguments->instance);
}
- rb_str_unlocktmp(arguments->string);
+ if (!RB_OBJ_FROZEN(arguments->string)) {
+ rb_str_unlocktmp(arguments->string);
+ }
return Qnil;
}
diff --git a/proc.c b/proc.c
index 98aa10d59f..8543110476 100644
--- a/proc.c
+++ b/proc.c
@@ -1562,7 +1562,8 @@ rb_sym_to_proc(VALUE sym)
RARRAY_ASET(sym_proc_cache, index, procval);
return RB_GC_GUARD(procval);
- } else {
+ }
+ else {
return sym_proc_new(rb_cProc, sym);
}
}
diff --git a/re.c b/re.c
index e666a7c3d4..b47538d594 100644
--- a/re.c
+++ b/re.c
@@ -3507,7 +3507,8 @@ rb_reg_regcomp(VALUE str)
return reg_cache;
return reg_cache = rb_reg_new_str(str, 0);
- } else {
+ }
+ else {
return rb_reg_new_str(str, 0);
}
}
diff --git a/test/ruby/test_io_buffer.rb b/test/ruby/test_io_buffer.rb
index 55296c1f23..70c5ef061d 100644
--- a/test/ruby/test_io_buffer.rb
+++ b/test/ruby/test_io_buffer.rb
@@ -121,6 +121,16 @@ class TestIOBuffer < Test::Unit::TestCase
end
end
+ def test_string_mapped_buffer_frozen
+ string = "Hello World".freeze
+ IO::Buffer.for(string) do |buffer|
+ assert_raise IO::Buffer::AccessError, "Buffer is not writable!" do
+ buffer.set_string("abc")
+ end
+ assert_equal "H".ord, buffer.get_value(:U8, 0)
+ end
+ end
+
def test_non_string
not_string = Object.new
diff --git a/test/ruby/test_zjit.rb b/test/ruby/test_zjit.rb
index 7b582df2f5..d7249053e5 100644
--- a/test/ruby/test_zjit.rb
+++ b/test/ruby/test_zjit.rb
@@ -31,6 +31,20 @@ class TestZJIT < Test::Unit::TestCase
}
end
+ def test_putstring
+ assert_compiles '""', %q{
+ def test = "#{""}"
+ test
+ }, insns: [:putstring]
+ end
+
+ def test_putchilldedstring
+ assert_compiles '""', %q{
+ def test = ""
+ test
+ }, insns: [:putchilledstring]
+ end
+
def test_leave_param
assert_compiles '5', %q{
def test(n) = n
diff --git a/thread.c b/thread.c
index 41bd6c9ec6..5575157728 100644
--- a/thread.c
+++ b/thread.c
@@ -6229,7 +6229,8 @@ threadptr_interrupt_exec_exec(rb_thread_t *th)
if (task) {
if (task->flags & rb_interrupt_exec_flag_new_thread) {
rb_thread_create(task->func, task->data);
- } else {
+ }
+ else {
(*task->func)(task->data);
}
ruby_xfree(task);
diff --git a/tool/auto-style.rb b/tool/auto-style.rb
index d2b007bd51..25055ace7d 100644..100755
--- a/tool/auto-style.rb
+++ b/tool/auto-style.rb
@@ -69,7 +69,7 @@ class Git
def git(*args)
cmd = ['git', *args].shelljoin
puts "+ #{cmd}"
- unless with_clean_env { system(cmd) }
+ unless with_clean_env { system('git', *args) }
abort "Failed to run: #{cmd}"
end
end
@@ -173,6 +173,10 @@ IGNORED_FILES = [
%r{\Asample/trick[^/]*/},
]
+DIFFERENT_STYLE_FILES = %w[
+ addr2line.c io_buffer.c prism*.c scheduler.c
+]
+
oldrev, newrev, pushref = ARGV
unless dry_run = pushref.empty?
branch = IO.popen(['git', 'rev-parse', '--symbolic', '--abbrev-ref', pushref], &:read).strip
@@ -194,7 +198,7 @@ if files.empty?
exit
end
-trailing = eofnewline = expandtab = false
+trailing = eofnewline = expandtab = indent = false
edited_files = files.select do |f|
src = File.binread(f) rescue next
@@ -202,6 +206,8 @@ edited_files = files.select do |f|
trailing0 = false
expandtab0 = false
+ indent0 = false
+
src.gsub!(/^.*$/).with_index do |line, lineno|
trailing = trailing0 = true if line.sub!(/[ \t]+$/, '')
line
@@ -225,7 +231,15 @@ edited_files = files.select do |f|
end
end
- if trailing0 or eofnewline0 or expandtab0
+ if File.fnmatch?("*.[ch]", f, File::FNM_PATHNAME) &&
+ !DIFFERENT_STYLE_FILES.any? {|pat| File.fnmatch?(pat, f, File::FNM_PATHNAME)}
+ src.gsub!(/^\w+\([^(\n)]*?\)\K[ \t]*(?=\{$)/, "\n")
+ src.gsub!(/^([ \t]*)\}\K[ \t]*(?=else\b)/, "\n" '\1')
+ src.gsub!(/^[ \t]*\}\n\K\n+(?=[ \t]*else\b)/, '')
+ indent = indent0 = true
+ end
+
+ if trailing0 or eofnewline0 or expandtab0 or indent0
File.binwrite(f, src)
true
end
@@ -236,6 +250,7 @@ else
msg = [('remove trailing spaces' if trailing),
('append newline at EOF' if eofnewline),
('expand tabs' if expandtab),
+ ('adjust indents' if indent),
].compact
message = "* #{msg.join(', ')}. [ci skip]"
if expandtab
diff --git a/vm.c b/vm.c
index 6f20d43ee4..7b0775fbb3 100644
--- a/vm.c
+++ b/vm.c
@@ -2982,6 +2982,7 @@ rb_vm_update_references(void *ptr)
if (ptr) {
rb_vm_t *vm = ptr;
+ vm->self = rb_gc_location(vm->self);
vm->mark_object_ary = rb_gc_location(vm->mark_object_ary);
vm->load_path = rb_gc_location(vm->load_path);
vm->load_path_snapshot = rb_gc_location(vm->load_path_snapshot);
@@ -3068,6 +3069,8 @@ rb_vm_mark(void *ptr)
rb_gc_mark_maybe(*list->varptr);
}
+ rb_gc_mark_movable(vm->self);
+
if (vm->main_namespace) {
rb_namespace_entry_mark((void *)vm->main_namespace);
}
diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs
index 32ea9e1c15..286f3f39b4 100644
--- a/zjit/src/codegen.rs
+++ b/zjit/src/codegen.rs
@@ -252,6 +252,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
Insn::NewArray { elements, state } => gen_new_array(jit, asm, elements, &function.frame_state(*state)),
Insn::NewRange { low, high, flag, state } => gen_new_range(asm, opnd!(low), opnd!(high), *flag, &function.frame_state(*state)),
Insn::ArrayDup { val, state } => gen_array_dup(asm, opnd!(val), &function.frame_state(*state)),
+ Insn::StringCopy { val, chilled } => gen_string_copy(asm, opnd!(val), *chilled),
Insn::Param { idx } => unreachable!("block.insns should not have Insn::Param({idx})"),
Insn::Snapshot { .. } => return Some(()), // we don't need to do anything for this instruction at the moment
Insn::Jump(branch) => return gen_jump(jit, asm, branch),
@@ -611,6 +612,17 @@ fn gen_send_without_block_direct(
Some(ret)
}
+/// Compile a string resurrection
+fn gen_string_copy(asm: &mut Assembler, recv: Opnd, chilled: bool) -> Opnd {
+ asm_comment!(asm, "call rb_ec_str_resurrect");
+ // TODO: split rb_ec_str_resurrect into separate functions
+ let chilled = if chilled { Opnd::Imm(1) } else { Opnd::Imm(0) };
+ asm.ccall(
+ rb_ec_str_resurrect as *const u8,
+ vec![EC, recv, chilled],
+ )
+}
+
/// Compile an array duplication instruction
fn gen_array_dup(
asm: &mut Assembler,
diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs
index 17b4aad6cf..c67f25451a 100644
--- a/zjit/src/hir.rs
+++ b/zjit/src/hir.rs
@@ -396,7 +396,7 @@ pub enum Insn {
/// SSA block parameter. Also used for function parameters in the function's entry block.
Param { idx: usize },
- StringCopy { val: InsnId },
+ StringCopy { val: InsnId, chilled: bool },
StringIntern { val: InsnId },
/// Put special object (VMCORE, CBASE, etc.) based on value_type
@@ -602,7 +602,7 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> {
Insn::ArraySet { array, idx, val } => { write!(f, "ArraySet {array}, {idx}, {val}") }
Insn::ArrayDup { val, .. } => { write!(f, "ArrayDup {val}") }
Insn::HashDup { val, .. } => { write!(f, "HashDup {val}") }
- Insn::StringCopy { val } => { write!(f, "StringCopy {val}") }
+ Insn::StringCopy { val, .. } => { write!(f, "StringCopy {val}") }
Insn::Test { val } => { write!(f, "Test {val}") }
Insn::IsNil { val } => { write!(f, "IsNil {val}") }
Insn::Jump(target) => { write!(f, "Jump {target}") }
@@ -978,7 +978,7 @@ impl Function {
}
},
Return { val } => Return { val: find!(*val) },
- StringCopy { val } => StringCopy { val: find!(*val) },
+ StringCopy { val, chilled } => StringCopy { val: find!(*val), chilled: *chilled },
StringIntern { val } => StringIntern { val: find!(*val) },
Test { val } => Test { val: find!(*val) },
&IsNil { val } => IsNil { val: find!(val) },
@@ -1623,7 +1623,7 @@ impl Function {
worklist.push_back(high);
worklist.push_back(state);
}
- Insn::StringCopy { val }
+ Insn::StringCopy { val, .. }
| Insn::StringIntern { val }
| Insn::Return { val }
| Insn::Defined { v: val, .. }
@@ -2142,10 +2142,14 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
let value_type = SpecialObjectType::from(get_arg(pc, 0).as_u32());
state.stack_push(fun.push_insn(block, Insn::PutSpecialObject { value_type }));
}
- YARVINSN_putstring | YARVINSN_putchilledstring => {
- // TODO(max): Do something different for chilled string
+ YARVINSN_putstring => {
let val = fun.push_insn(block, Insn::Const { val: Const::Value(get_arg(pc, 0)) });
- let insn_id = fun.push_insn(block, Insn::StringCopy { val });
+ let insn_id = fun.push_insn(block, Insn::StringCopy { val, chilled: false });
+ state.stack_push(insn_id);
+ }
+ YARVINSN_putchilledstring => {
+ let val = fun.push_insn(block, Insn::Const { val: Const::Value(get_arg(pc, 0)) });
+ let insn_id = fun.push_insn(block, Insn::StringCopy { val, chilled: true });
state.stack_push(insn_id);
}
YARVINSN_putself => { state.stack_push(self_param); }