Skip to content

Commit 4f59783

Browse files
authored
Merge pull request ruby#56 from Shopify/ujit-variadic-cfunc
Implement support for variadic C functions
2 parents bace91c + 1e5d5e9 commit 4f59783

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

bootstraptest/test_ujit.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,17 @@ def foo
8181
foo()
8282
}
8383

84+
# The hash method is a C function and uses the self argument
85+
assert_equal 'true', %q{
86+
def lehashself
87+
hash
88+
end
89+
90+
a = lehashself
91+
b = lehashself
92+
a == b
93+
}
94+
8495
# Method redefinition (code invalidation) test
8596
assert_equal '1', %q{
8697
def ret1

ujit_codegen.c

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,8 +1067,14 @@ gen_oswb_cfunc(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb_c
10671067
{
10681068
const rb_method_cfunc_t *cfunc = UNALIGNED_MEMBER_PTR(cme->def, body.cfunc);
10691069

1070-
// Don't JIT if the argument count doesn't match
1071-
if (cfunc->argc < 0 || cfunc->argc != argc)
1070+
// If the function expects a Ruby array of arguments
1071+
if (cfunc->argc < 0 && cfunc->argc != -1)
1072+
{
1073+
return false;
1074+
}
1075+
1076+
// If the argument count doesn't match
1077+
if (cfunc->argc >= 0 && cfunc->argc != argc)
10721078
{
10731079
return false;
10741080
}
@@ -1201,13 +1207,26 @@ gen_oswb_cfunc(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb_c
12011207
// Copy SP into RAX because REG_SP will get overwritten
12021208
lea(cb, RAX, ctx_sp_opnd(ctx, 0));
12031209

1204-
// Copy the arguments from the stack to the C argument registers
1205-
// self is the 0th argument and is at index argc from the stack top
1206-
for (int32_t i = 0; i < argc + 1; ++i)
1210+
// Non-variadic method
1211+
if (cfunc->argc >= 0)
1212+
{
1213+
// Copy the arguments from the stack to the C argument registers
1214+
// self is the 0th argument and is at index argc from the stack top
1215+
for (int32_t i = 0; i < argc + 1; ++i)
1216+
{
1217+
x86opnd_t stack_opnd = mem_opnd(64, RAX, -(argc + 1 - i) * SIZEOF_VALUE);
1218+
x86opnd_t c_arg_reg = C_ARG_REGS[i];
1219+
mov(cb, c_arg_reg, stack_opnd);
1220+
}
1221+
}
1222+
// Variadic method
1223+
if (cfunc->argc == -1)
12071224
{
1208-
x86opnd_t stack_opnd = mem_opnd(64, RAX, -(argc + 1 - i) * 8);
1209-
x86opnd_t c_arg_reg = C_ARG_REGS[i];
1210-
mov(cb, c_arg_reg, stack_opnd);
1225+
// The method gets a pointer to the first argument
1226+
// rb_f_puts(int argc, VALUE *argv, VALUE recv)
1227+
mov(cb, C_ARG_REGS[0], imm_opnd(argc));
1228+
lea(cb, C_ARG_REGS[1], mem_opnd(64, RAX, -(argc) * SIZEOF_VALUE));
1229+
mov(cb, C_ARG_REGS[2], mem_opnd(64, RAX, -(argc + 1) * SIZEOF_VALUE));
12111230
}
12121231

12131232
// Pop the C function arguments from the stack (in the caller)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy