[前][次][番号順一覧][スレッド一覧]

ruby-changes:73236

From: Takashi <ko1@a...>
Date: Tue, 30 Aug 2022 01:03:28 +0900 (JST)
Subject: [ruby-changes:73236] 330c9e9850 (master): Port anytostring, intern, and toregexp (https://github.com/Shopify/ruby/pull/348)

https://git.ruby-lang.org/ruby.git/commit/?id=330c9e9850

From 330c9e98506d421778c8f2581a23ba44e4663e06 Mon Sep 17 00:00:00 2001
From: Takashi Kokubun <takashikkbn@g...>
Date: Mon, 1 Aug 2022 20:39:31 -0700
Subject: Port anytostring, intern, and toregexp
 (https://github.com/Shopify/ruby/pull/348)

* Port anytostring, intern, and toregexp

* Port getspecial to the new backend (#349)

PR: https://github.com/Shopify/ruby/pull/349
---
 bootstraptest/test_yjit.rb |  16 ++++++
 yjit/src/codegen.rs        | 122 ++++++++++++++++++++++-----------------------
 2 files changed, 77 insertions(+), 61 deletions(-)

diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 2f8c6a8f18..b8374746f7 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -3087,3 +3087,19 @@ assert_equal 'foo', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L3087
     foo = Foo.new
     foo.foo
 }
+
+# anytostring, intern
+assert_equal 'true', %q{
+    def foo()
+      :"#{true}"
+    end
+    foo()
+}
+
+# toregexp
+assert_equal '/true/', %q{
+    def foo()
+      /#{true}/
+    end
+    foo().inspect
+}
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index ee52800699..36cdd55573 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -5338,31 +5338,28 @@ fn gen_setglobal( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L5338
     KeepCompiling
 }
 
-/*
 fn gen_anytostring(
     jit: &mut JITState,
     ctx: &mut Context,
-    cb: &mut CodeBlock,
+    asm: &mut Assembler,
     _ocb: &mut OutlinedCb,
 ) -> CodegenStatus {
     // Save the PC and SP since we might call #to_s
-    jit_prepare_routine_call(jit, ctx, cb, REG0);
+    jit_prepare_routine_call(jit, ctx, asm);
 
     let str = ctx.stack_pop(1);
     let val = ctx.stack_pop(1);
 
-    mov(cb, C_ARG_REGS[0], str);
-    mov(cb, C_ARG_REGS[1], val);
-
-    call_ptr(cb, REG0, rb_obj_as_string_result as *const u8);
+    let val = asm.ccall(rb_obj_as_string_result as *const u8, vec![str, val]);
 
     // Push the return value
     let stack_ret = ctx.stack_push(Type::TString);
-    mov(cb, stack_ret, RAX);
+    asm.mov(stack_ret, val);
 
     KeepCompiling
 }
 
+/*
 fn gen_objtostring(
     jit: &mut JITState,
     ctx: &mut Context,
@@ -5399,25 +5396,23 @@ fn gen_objtostring( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L5396
         gen_send_general(jit, ctx, cb, ocb, cd, None)
     }
 }
+*/
 
 fn gen_intern(
     jit: &mut JITState,
     ctx: &mut Context,
-    cb: &mut CodeBlock,
+    asm: &mut Assembler,
     _ocb: &mut OutlinedCb,
 ) -> CodegenStatus {
     // Save the PC and SP because we might allocate
-    jit_prepare_routine_call(jit, ctx, cb, REG0);
+    jit_prepare_routine_call(jit, ctx, asm);
 
     let str = ctx.stack_pop(1);
-
-    mov(cb, C_ARG_REGS[0], str);
-
-    call_ptr(cb, REG0, rb_str_intern as *const u8);
+    let sym = asm.ccall(rb_str_intern as *const u8, vec![str]);
 
     // Push the return value
     let stack_ret = ctx.stack_push(Type::Unknown);
-    mov(cb, stack_ret, RAX);
+    asm.mov(stack_ret, sym);
 
     KeepCompiling
 }
@@ -5425,7 +5420,7 @@ fn gen_intern( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L5420
 fn gen_toregexp(
     jit: &mut JITState,
     ctx: &mut Context,
-    cb: &mut CodeBlock,
+    asm: &mut Assembler,
     _ocb: &mut OutlinedCb,
 ) -> CodegenStatus {
     let opt = jit_get_arg(jit, 0).as_i64();
@@ -5433,34 +5428,43 @@ fn gen_toregexp( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L5428
 
     // Save the PC and SP because this allocates an object and could
     // raise an exception.
-    jit_prepare_routine_call(jit, ctx, cb, REG0);
+    jit_prepare_routine_call(jit, ctx, asm);
 
     let values_ptr = ctx.sp_opnd(-((SIZEOF_VALUE as isize) * (cnt as isize)));
     ctx.stack_pop(cnt);
 
-    mov(cb, C_ARG_REGS[0], imm_opnd(0));
-    mov(cb, C_ARG_REGS[1], imm_opnd(cnt.try_into().unwrap()));
-    lea(cb, C_ARG_REGS[2], values_ptr);
-    call_ptr(cb, REG0, rb_ary_tmp_new_from_values as *const u8);
+    let ary = asm.ccall(
+        rb_ary_tmp_new_from_values as *const u8,
+        vec![
+            Opnd::Imm(0),
+            Opnd::UImm(jit_get_arg(jit, 1).as_u64()),
+            values_ptr,
+        ]
+    );
 
     // Save the array so we can clear it later
-    push(cb, RAX);
-    push(cb, RAX); // Alignment
-    mov(cb, C_ARG_REGS[0], RAX);
-    mov(cb, C_ARG_REGS[1], imm_opnd(opt));
-    call_ptr(cb, REG0, rb_reg_new_ary as *const u8);
+    asm.cpush(ary);
+    asm.cpush(ary); // Alignment
+
+    let val = asm.ccall(
+        rb_reg_new_ary as *const u8,
+        vec![
+            ary,
+            Opnd::Imm(opt),
+        ]
+    );
 
     // The actual regex is in RAX now.  Pop the temp array from
     // rb_ary_tmp_new_from_values into C arg regs so we can clear it
-    pop(cb, REG1); // Alignment
-    pop(cb, C_ARG_REGS[0]);
+    let ary = asm.cpop(); // Alignment
+    asm.cpop_into(ary);
 
     // The value we want to push on the stack is in RAX right now
     let stack_ret = ctx.stack_push(Type::Unknown);
-    mov(cb, stack_ret, RAX);
+    asm.mov(stack_ret, val);
 
     // Clear the temp array.
-    call_ptr(cb, REG0, rb_ary_clear as *const u8);
+    asm.ccall(rb_ary_clear as *const u8, vec![ary]);
 
     KeepCompiling
 }
@@ -5468,7 +5472,7 @@ fn gen_toregexp( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L5472
 fn gen_getspecial(
     jit: &mut JITState,
     ctx: &mut Context,
-    cb: &mut CodeBlock,
+    asm: &mut Assembler,
     _ocb: &mut OutlinedCb,
 ) -> CodegenStatus {
     // This takes two arguments, key and type
@@ -5484,65 +5488,63 @@ fn gen_getspecial( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L5488
         // Fetch a "special" backref based on a char encoded by shifting by 1
 
         // Can raise if matchdata uninitialized
-        jit_prepare_routine_call(jit, ctx, cb, REG0);
+        jit_prepare_routine_call(jit, ctx, asm);
 
         // call rb_backref_get()
-        add_comment(cb, "rb_backref_get");
-        call_ptr(cb, REG0, rb_backref_get as *const u8);
-        mov(cb, C_ARG_REGS[0], RAX);
+        asm.comment("rb_backref_get");
+        let backref = asm.ccall(rb_backref_get as *const u8, vec![]);
 
         let rt_u8: u8 = (rtype >> 1).try_into().unwrap();
-        match rt_u8.into() {
+        let val = match rt_u8.into() {
             '&' => {
-                add_comment(cb, "rb_reg_last_match");
-                call_ptr(cb, REG0, rb_reg_last_match as *const u8);
+                asm.comment("rb_reg_last_match");
+                asm.ccall(rb_reg_last_match as *const u8, vec![backref])
             }
             '`' => {
-                add_comment(cb, "rb_reg_match_pre");
-                call_ptr(cb, REG0, rb_reg_match_pre as *const u8);
+                asm.comment("rb_reg_match_pre");
+                asm.ccall(rb_reg_match_pre as *const u8, vec![backref])
             }
             '\'' => {
-                add_comment(cb, "rb_reg_match_post");
-                call_ptr(cb, REG0, rb_reg_match_post as *const u8);
+                asm.comment("rb_reg_match_post");
+                asm.ccall(rb_reg_match_post as *const u8, vec![backref])
             }
             '+' => {
-                add_comment(cb, "rb_reg_match_last");
-                call_ptr(cb, REG0, rb_reg_match_last as *const u8);
+                asm.comment("rb_reg_match_last");
+                asm.ccall(rb_reg_match_last as *const u8, vec![backref])
             }
             _ => panic!("invalid back-ref"),
-        }
+        };
 
         let stack_ret = ctx.stack_push(Type::Unknown);
-        mov(cb, stack_ret, RAX);
+        asm.mov(stack_ret, val);
 
         KeepCompiling
     } else {
         // Fetch the N-th match from the last backref based on type shifted by 1
 
         // Can raise if matchdata uninitialized
-        jit_prepare_routine_call(jit, ctx, cb, REG0);
+        jit_prepare_routine_call(jit, ctx, asm);
 
         // call rb_backref_get()
-        add_comment(cb, "rb_backref_get");
-        call_ptr(cb, REG0, rb_backref_get as *const u8);
+        asm.comment("rb_backref_get");
+        let backref = asm.ccall(rb_backref_get as *const u8, vec![]);
 
         // rb_reg_nth_match((int)(type >> 1), backref);
-        add_comment(cb, "rb_reg_nth_match");
-        mov(
-            cb,
-            C_ARG_REGS[0],
-            imm_opnd((rtype >> 1).try_into().unwrap()),
+        asm.comment("rb_reg_nth_match");
+        let val = asm.ccall(
+            rb_reg_nth_match as *const u8,
+            vec![
+                Opnd::Imm((rtype >> 1).try_into().unwrap()),
+                backref,
+            ]
         );
-        mov(cb, C_ARG_REGS[1], RAX);
-        call_ptr(cb, REG0, rb_reg_nth_match as *const u8);
 
         let stack_ret = ctx.stack_push(Type::Unknown);
-        mov(cb, stack_ret, RAX);
+        asm.mov(stack_ret, val);
 
         KeepCompiling
     }
 }
-*/
 
 fn gen_getclassvariable(
     jit: &mut JITState,
@@ -6052,13 +6054,11 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> { https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L6054
 
         YARVINSN_getglobal => Some(gen_getglobal),
         YARVINSN_setglobal => Some(gen_setglobal),
-        /*
         YARVINSN_anytostring => Some(gen_anytostring),
-        YARVINSN_objtostring => Some(gen_objtostring),
+        //YARVINSN_objtostring => Some(gen_objtostring),
         YARVINSN_intern => Some(gen_intern),
         YARVINSN_toregexp => Some(gen_toregexp),
         YARVINSN_getspecial => Some(gen_getspecial),
-        */
         YARVINSN_getclassvariable => Some(gen_getclassvariable),
         YARVINSN_setclassvariable => Some(gen_setclassvariable),
 
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]