8000 Merge pull request #230 from jhawthorn/invokebuiltin · github/ruby@5fd43aa · GitHub
[go: up one dir, main page]

Skip to content

Commit 5fd43aa

Browse files
authored
Merge pull request #230 from jhawthorn/invokebuiltin
Implement invokebuiltin
2 parents b53a06f + 2d6bfad commit 5fd43aa

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

bootstraptest/test_yjit.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,18 @@ def make_str(foo, bar)
12101210
make_str("foo", 123)
12111211
}
12121212

1213+
# test invokebuiltin as used in struct assignment
1214+
assert_equal '123', %q{
1215+
def foo(obj)
1216+
obj.foo = 123
1217+
end
1218+
1219+
struct = Struct.new(:foo)
1220+
obj = struct.new
1221+
foo(obj)
1222+
foo(obj)
1223+
}
1224+
12131225
# test invokebuiltin_delegate as used inside Dir.open
12141226
assert_equal '.', %q{
12151227
def foo(path)

test/ruby/test_yjit.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,19 @@ def make_str(foo, bar)
310310
RUBY
311311
end
312312

< 8000 /code>313+
def test_invokebuiltin
314+
assert_compiles(<<~RUBY)
315+
def foo(obj)
316+
obj.foo = 123
317+
obj.bar = 123
318+
end
319+
320+
Foo = Struct.new(:foo, :bar)
321+
foo(Foo.new(123))
322+
foo(Foo.new(123))
323+
RUBY
324+
end
325+
313326
def test_super_iseq
314327
assert_compiles(<<~'RUBY', insns: %i[invokesuper opt_plus opt_mult], result: 15)
315328
class A

yjit_codegen.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4135,6 +4135,40 @@ gen_getblockparamproxy(jitstate_t *jit, ctx_t *ctx)
41354135
return YJIT_KEEP_COMPILING;
41364136
}
41374137

4138+
static codegen_status_t
4139+
gen_invokebuiltin(jitstate_t *jit, ctx_t *ctx)
4140+
{
4141+
const struct rb_builtin_function *bf = (struct rb_builtin_function *)jit_get_arg(jit, 0);
4142+
4143+
// ec, self, and arguments
4144+
if (bf->argc + 2 > NUM_C_ARG_REGS) {
4145+
return YJIT_CANT_COMPILE;
4146+
}
4147+
4148+
// If the calls don't allocate, do they need up to date PC, SP?
4149+
jit_prepare_routine_call(jit, ctx, REG0);
4150+
4151+
// Call the builtin func (ec, recv, arg1, arg2, ...)
4152+
mov(cb, C_ARG_REGS[0], REG_EC);
4153+
mov(cb, C_ARG_REGS[1], member_opnd(REG_CFP, rb_control_frame_t, self));
4154+
4155+
// Copy arguments from locals
4156+
for (int32_t i = 0; i < bf->argc; i++) {
4157+
x86opnd_t stack_opnd = ctx_stack_opnd(ctx, bf->argc - i - 1);
4158+
x86opnd_t c_arg_reg = C_ARG_REGS[2 + i];
4159+
mov(cb, c_arg_reg, stack_opnd);
4160+
}
4161+
4162+
call_ptr(cb, REG0, (void *)bf->func_ptr);
4163+
4164+
// Push the return value
4165+
ctx_stack_pop(ctx, bf->argc);
4166+
x86opnd_t stack_ret = ctx_stack_push(ctx, TYPE_UNKNOWN);
4167+
mov(cb, stack_ret, RAX);
4168+
4169+
return YJIT_KEEP_COMPILING;
4170+
}
4171+
41384172
// opt_invokebuiltin_delegate calls a builtin function, like
41394173
// invokebuiltin does, but instead of taking arguments from the top of the
41404174
// stack uses the argument locals (and self) from the current method.
@@ -4144,7 +4178,8 @@ gen_opt_invokebuiltin_delegate(jitstate_t *jit, ctx_t *ctx)
41444178
const struct rb_builtin_function *bf = (struct rb_builtin_function *)jit_get_arg(jit, 0);
41454179
int32_t start_index = (int32_t)jit_get_arg(jit, 1);
41464180

4147-
if (bf->argc + 2 >= NUM_C_ARG_REGS) {
4181+
// ec, self, and arguments
4182+
if (bf->argc + 2 > NUM_C_ARG_REGS) {
41484183
return YJIT_CANT_COMPILE;
41494184
}
41504185

@@ -4386,6 +4421,7 @@ yjit_init_codegen(void)
43864421
yjit_reg_op(BIN(opt_length), gen_opt_length);
43874422
yjit_reg_op(BIN(opt_regexpmatch2), gen_opt_regexpmatch2);
43884423
yjit_reg_op(BIN(opt_getinlinecache), gen_opt_getinlinecache);
4424+
yjit_reg_op(BIN(invokebuiltin), gen_invokebuiltin);
43894425
yjit_reg_op(BIN(opt_invokebuiltin_delegate), gen_opt_invokebuiltin_delegate);
43904426
yjit_reg_op(BIN(opt_invokebuiltin_delegate_leave), gen_opt_invokebuiltin_delegate);
43914427
yjit_reg_op(BIN(opt_case_dispatch), gen_opt_case_dispatch);

0 commit comments

Comments
 (0)
0