diff options
-rw-r--r-- | .github/workflows/check_misc.yml | 6 | ||||
-rw-r--r-- | compile.c | 3 | ||||
-rw-r--r-- | gc.c | 1 | ||||
-rw-r--r-- | hash.c | 1 | ||||
-rw-r--r-- | io_buffer.c | 8 | ||||
-rw-r--r-- | proc.c | 3 | ||||
-rw-r--r-- | re.c | 3 | ||||
-rw-r--r-- | test/ruby/test_io_buffer.rb | 10 | ||||
-rw-r--r-- | test/ruby/test_zjit.rb | 14 | ||||
-rw-r--r-- | thread.c | 3 | ||||
-rwxr-xr-x[-rw-r--r--] | tool/auto-style.rb | 21 | ||||
-rw-r--r-- | vm.c | 3 | ||||
-rw-r--r-- | zjit/src/codegen.rs | 12 | ||||
-rw-r--r-- | zjit/src/hir.rs | 18 |
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: EMAIL: [email protected] 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: | @@ -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; } @@ -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(); @@ -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; } @@ -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); } } @@ -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 @@ -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 @@ -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); } |