8000 Implement send with alias method (#23) · github/ruby@667b355 · GitHub
[go: up one dir, main page]

Skip to content

Commit 667b355

Browse files
authored
Implement send with alias method (#23)
* Implement send with alias method * Add alias_method tests
1 parent 5d97c67 commit 667b355

File tree

3 files changed

+106
-44
lines changed

3 files changed

+106
-44
lines changed

bootstraptest/test_yjit.rb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,52 @@ def foo
130130
foo()
131131
}
132132

133+
# Method aliasing
134+
assert_equal '42', %q{
135+
class Foo
136+
def method_a
137+
42
138+
end
139+
140+
alias method_b method_a
141+
142+
def method_a
143+
:somethingelse
144+
end
145+
end
146+
147+
@obj = Foo.new
148+
149+
def test
150+
@obj.method_b
151+
end
152+
153+
test
154+
test
155+
}
156+
157+
# Method aliasing with method from parent class
158+
assert_equal '777', %q{
159+
class A
160+
def method_a
161+
777
162+
end
163+
end
164+
165+
class B < A
166+
alias method_b method_a
167+
end
168+
169+
@obj = B.new
170+
171+
def test
172+
@obj.method_b
173+
end
174+
175+
test
176+
test
177+
}
178+
133179
# The hash method is a C function and uses the self argument
134180
assert_equal 'true', %q{
135181
def lehashself

vm_insnhelper.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3079,6 +3079,12 @@ aliased_callable_method_entry(const rb_callable_method_entry_t *me)
30793079
return cme;
30803080
}
30813081

3082+
const rb_callable_method_entry_t *
3083+
rb_aliased_callable_method_entry(const rb_callable_method_entry_t *me)
3084+
{
3085+
return aliased_callable_method_entry(me);
3086+
}
3087+
30823088
static VALUE
30833089
vm_call_alias(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
30843090
{

yjit_codegen.c

Lines changed: 54 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2092,6 +2092,9 @@ gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const r
20922092
return YJIT_END_BLOCK;
20932093
}
20942094

2095+
const rb_callable_method_entry_t *
2096+
rb_aliased_callable_method_entry(const rb_callable_method_entry_t *me);
2097+
20952098
static codegen_status_t
20962099
gen_send_general(jitstate_t *jit, ctx_t *ctx, struct rb_call_data *cd, rb_iseq_t *block)
20972100
{
@@ -2176,54 +2179,61 @@ gen_send_general(jitstate_t *jit, ctx_t *ctx, struct rb_call_data *cd, rb_iseq_t
21762179
// Method calls may corrupt types
21772180
ctx_clear_local_types(ctx);
21782181

2179-
switch (cme->def->type) {
2180-
case VM_METHOD_TYPE_ISEQ:
2181-
return gen_send_iseq(jit, ctx, ci, cme, block, argc);
2182-
case VM_METHOD_TYPE_CFUNC:
2183-
return gen_send_cfunc(jit, ctx, ci, cme, block, argc);
2184-
case VM_METHOD_TYPE_IVAR:
2185-
if (argc != 0) {
2186-
// Argument count mismatch. Getters take no arguments.
2187-
GEN_COUNTER_INC(cb, send_getter_arity);
2182+
// To handle the aliased method case (VM_METHOD_TYPE_ALIAS)
2183+
while (true) {
2184+
// switch on the method type
2185+
switch (cme->def->type) {
2186+
case VM_METHOD_TYPE_ISEQ:
2187+
return gen_send_iseq(jit, ctx, ci, cme, block, argc);
2188+
case VM_METHOD_TYPE_CFUNC:
2189+
return gen_send_cfunc(jit, ctx, ci, cme, block, argc);
2190+
case VM_METHOD_TYPE_IVAR:
2191+
if (argc != 0) {
2192+
// Argument count mismatch. Getters take no arguments.
2193+
GEN_COUNTER_INC(cb, send_getter_arity);
2194+
return YJIT_CANT_COMPILE;
2195+
}
2196+
else {
2197+
mov(cb, REG0, recv);
2198+
2199+
ID ivar_name = cme->def->body.attr.id;
2200+
return gen_get_ivar(jit, ctx, SEND_MAX_DEPTH, comptime_recv, ivar_name, recv_opnd, side_exit);
2201+
}
2202+
case VM_METHOD_TYPE_ATTRSET:
2203+
GEN_COUNTER_INC(cb, send_ivar_set_method);
21882204
return YJIT_CANT_COMPILE;
2205+
case VM_METHOD_TYPE_BMETHOD:
2206+
GEN_COUNTER_INC(cb, send_bmethod);
2207+
return YJIT_CANT_COMPILE;
2208+
case VM_METHOD_TYPE_ZSUPER:
2209+
GEN_COUNTER_INC(cb, send_zsuper_method);
2210+
return YJIT_CANT_COMPILE;
2211+
case VM_METHOD_TYPE_ALIAS: {
2212+
// Retrieve the alised method and re-enter the switch
2213+
cme = rb_aliased_callable_method_entry(cme);
2214+
continue;
21892215
}
2190-
else {
2191-
mov(cb, REG0, recv);
2192-
2193-
ID ivar_name = cme->def->body.attr.id;
2194-
return gen_get_ivar(jit, ctx, SEND_MAX_DEPTH, comptime_recv, ivar_name, recv_opnd, side_exit);
2216+
case VM_METHOD_TYPE_UNDEF:
2217+
GEN_COUNTER_INC(cb, send_undef_method);
2218+
return YJIT_CANT_COMPILE;
2219+
case VM_METHOD_TYPE_NOTIMPLEMENTED:
2220+
GEN_COUNTER_INC(cb, send_not_implemented_method);
2221+
return YJIT_CANT_COMPILE;
2222+
case VM_METHOD_TYPE_OPTIMIZED:
2223+
GEN_COUNTER_INC(cb, send_optimized_method);
2224+
return YJIT_CANT_COMPILE;
2225+
case VM_METHOD_TYPE_MISSING:
2226+
GEN_COUNTER_INC(cb, send_missing_method);
2227+
return YJIT_CANT_COMPILE;
2228+
case VM_METHOD_TYPE_REFINED:
2229+
GEN_COUNTER_INC(cb, send_refined_method);
2230+
return YJIT_CANT_COMPILE;
2231+
// no default case so compiler issues a warning if this is not exhaustive
21952232
}
2196-
case VM_METHOD_TYPE_ATTRSET:
2197-
GEN_COUNTER_INC(cb, send_ivar_set_method);
2198-
return YJIT_CANT_COMPILE;
2199-
case VM_METHOD_TYPE_BMETHOD:
2200-
GEN_COUNTER_INC(cb, send_bmethod);
2201-
return YJIT_CANT_COMPILE;
2202-
case VM_METHOD_TYPE_ZSUPER:
2203-
GEN_COUNTER_INC(cb, send_zsuper_method);
2204-
return YJIT_CANT_COMPILE;
2205-
case VM_METHOD_TYPE_ALIAS:
2206-
GEN_COUNTER_INC(cb, send_alias_method);
2207-
return YJIT_CANT_COMPILE;
2208-
case VM_METHOD_TYPE_UNDEF:
2209-
GEN_COUNTER_INC(cb, send_undef_method);
2210-
return YJIT_CANT_COMPILE;
2211-
case VM_METHOD_TYPE_NOTIMPLEMENTED:
2212-
GEN_COUNTER_INC(cb, send_not_implemented_method);
2213-
return YJIT_CANT_COMPILE;
2214-
case VM_METHOD_TYPE_OPTIMIZED:
2215-
GEN_COUNTER_INC(cb, send_optimized_method);
2216-
return YJIT_CANT_COMPILE;
2217-
case VM_METHOD_TYPE_MISSING:
2218-
GEN_COUNTER_INC(cb, send_missing_method);
2219-
return YJIT_CANT_COMPILE;
2220-
case VM_METHOD_TYPE_REFINED:
2221-
GEN_COUNTER_INC(cb, send_refined_method);
2222-
return YJIT_CANT_COMPILE;
2223-
// no default case so compiler issues a warning if this is not exhaustive
2224-
}
22252233

2226-
return YJIT_CANT_COMPILE;
2234+
// Unreachable
2235+
RUBY_ASSERT(false);
2236+
}
22272237
}
22282238

22292239
static codegen_status_t

0 commit comments

Comments
 (0)
0