Fix setting struct member by public_send

This commit is contained in:
Nobuyoshi Nakada 2021-11-21 00:31:51 +09:00
Родитель c5ec05d047
Коммит 8f3432cd44
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 7CD2805BFA3770C6
3 изменённых файлов: 14 добавлений и 7 удалений

Просмотреть файл

@ -489,6 +489,14 @@ module TestStruct
}
end
def test_public_send
klass = @Struct.new(:a)
x = klass.new(1)
assert_equal(1, x.public_send("a"))
assert_equal(42, x.public_send("a=", 42))
assert_equal(42, x.public_send("a"))
end
class TopStruct < Test::Unit::TestCase
include TestStruct

Просмотреть файл

@ -275,11 +275,11 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const
}
case OPTIMIZED_METHOD_TYPE_STRUCT_AREF:
vm_call_check_arity(calling, 0, argv);
ret = vm_call_opt_struct_aref0(ec, ec->cfp, calling);
ret = vm_call_opt_struct_aref0(ec, calling);
goto success;
case OPTIMIZED_METHOD_TYPE_STRUCT_ASET:
vm_call_check_arity(calling, 1, argv);
ret = vm_call_opt_struct_aset0(ec, ec->cfp, calling);
ret = vm_call_opt_struct_aset0(ec, calling, argv[0]);
goto success;
default:
rb_bug("vm_call0: unsupported optimized method type (%d)", vm_cc_cme(cc)->def->body.optimized.type);

Просмотреть файл

@ -3531,7 +3531,7 @@ vm_call_opt_block_call(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
}
static VALUE
vm_call_opt_struct_aref0(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling)
vm_call_opt_struct_aref0(rb_execution_context_t *ec, struct rb_calling_info *calling)
{
VALUE recv = calling->recv;
@ -3548,16 +3548,15 @@ vm_call_opt_struct_aref(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
{
RB_DEBUG_COUNTER_INC(ccf_opt_struct_aref);
VALUE ret = vm_call_opt_struct_aref0(ec, reg_cfp, calling);
VALUE ret = vm_call_opt_struct_aref0(ec, calling);
reg_cfp->sp -= 1;
return ret;
}
static VALUE
vm_call_opt_struct_aset0(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling)
vm_call_opt_struct_aset0(rb_execution_context_t *ec, struct rb_calling_info *calling, VALUE val)
{
VALUE recv = calling->recv;
VALUE val = *(reg_cfp->sp - 1);
VM_ASSERT(RB_TYPE_P(recv, T_STRUCT));
VM_ASSERT(vm_cc_cme(calling->cc)->def->type == VM_METHOD_TYPE_OPTIMIZED);
@ -3576,7 +3575,7 @@ vm_call_opt_struct_aset(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
{
RB_DEBUG_COUNTER_INC(ccf_opt_struct_aset);
VALUE ret = vm_call_opt_struct_aset0(ec, reg_cfp, calling);
VALUE ret = vm_call_opt_struct_aset0(ec, calling, *(reg_cfp->sp - 1));
reg_cfp->sp -= 2;
return ret;
}