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

ruby-changes:68803

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:13:37 +0900 (JST)
Subject: [ruby-changes:68803] f93f3d6aa1 (master): Implement support for variadic C functions

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

From f93f3d6aa164ea5bc01e596c84b7c525c41bb852 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Thu, 25 Feb 2021 12:09:29 -0500
Subject: Implement support for variadic C functions

---
 bootstraptest/test_ujit.rb | 11 +++++++++++
 ujit_codegen.c             | 35 +++++++++++++++++++++++++++--------
 2 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/bootstraptest/test_ujit.rb b/bootstraptest/test_ujit.rb
index a5252d4570..0f67c6ebbb 100644
--- a/bootstraptest/test_ujit.rb
+++ b/bootstraptest/test_ujit.rb
@@ -81,6 +81,17 @@ assert_normal_exit %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ujit.rb#L81
   foo()
 }
 
+# The hash method is a C function and uses the self argument
+assert_equal 'true', %q{
+    def lehashself
+        hash
+    end
+
+    a = lehashself
+    b = lehashself
+    a == b
+}
+
 # Method redefinition (code invalidation) test
 assert_equal '1', %q{
     def ret1
diff --git a/ujit_codegen.c b/ujit_codegen.c
index 24767e1b50..6ac6dc013c 100644
--- a/ujit_codegen.c
+++ b/ujit_codegen.c
@@ -1067,8 +1067,14 @@ gen_oswb_cfunc(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb_c https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1067
 {
     const rb_method_cfunc_t *cfunc = UNALIGNED_MEMBER_PTR(cme->def, body.cfunc);
 
-    // Don't JIT if the argument count doesn't match
-    if (cfunc->argc < 0 || cfunc->argc != argc)
+    // If the function expects a Ruby array of arguments
+    if (cfunc->argc < 0 && cfunc->argc != -1)
+    {
+        return false;
+    }
+
+    // If the argument count doesn't match
+    if (cfunc->argc >= 0 && cfunc->argc != argc)
     {
         return false;
     }
@@ -1201,13 +1207,26 @@ gen_oswb_cfunc(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb_c https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1207
     // Copy SP into RAX because REG_SP will get overwritten
     lea(cb, RAX, ctx_sp_opnd(ctx, 0));
 
-    // Copy the arguments from the stack to the C argument registers
-    // self is the 0th argument and is at index argc from the stack top
-    for (int32_t i = 0; i < argc + 1; ++i)
+    // Non-variadic method
+    if (cfunc->argc >= 0)
+    {
+        // Copy the arguments from the stack to the C argument registers
+        // self is the 0th argument and is at index argc from the stack top
+        for (int32_t i = 0; i < argc + 1; ++i)
+        {
+            x86opnd_t stack_opnd = mem_opnd(64, RAX, -(argc + 1 - i) * SIZEOF_VALUE);
+            x86opnd_t c_arg_reg = C_ARG_REGS[i];
+            mov(cb, c_arg_reg, stack_opnd);
+        }
+    }
+    // Variadic method
+    if (cfunc->argc == -1)
     {
-        x86opnd_t stack_opnd = mem_opnd(64, RAX, -(argc + 1 - i) * 8);
-        x86opnd_t c_arg_reg = C_ARG_REGS[i];
-        mov(cb, c_arg_reg, stack_opnd);
+        // The method gets a pointer to the first argument
+        // rb_f_puts(int argc, VALUE *argv, VALUE recv)
+        mov(cb, C_ARG_REGS[0], imm_opnd(argc));
+        lea(cb, C_ARG_REGS[1], mem_opnd(64, RAX, -(argc) * SIZEOF_VALUE));
+        mov(cb, C_ARG_REGS[2], mem_opnd(64, RAX, -(argc + 1) * SIZEOF_VALUE));
     }
 
     // Pop the C function arguments from the stack (in the caller)
-- 
cgit v1.2.1


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

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