diff options
author | Koichi Sasada <[email protected]> | 2021-11-18 11:01:31 +0900 |
---|---|---|
committer | Koichi Sasada <[email protected]> | 2021-11-19 08:32:39 +0900 |
commit | 82ea2870188d66aa75a99f03b4e7fdd1750aa196 (patch) | |
tree | 6ae732893312619a03e8dee23418a52df784d1f8 /vm_eval.c | |
parent | be71c95b88019a1ca7a030a757ce343b743d8aff (diff) |
optimize `Struct` getter/setter
Introduce new optimized method type
`OPTIMIZED_METHOD_TYPE_STRUCT_AREF/ASET` with index information.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/5131
Diffstat (limited to 'vm_eval.c')
-rw-r--r-- | vm_eval.c | 39 |
1 files changed, 23 insertions, 16 deletions
@@ -163,6 +163,19 @@ vm_call0_cfunc(rb_execution_context_t *ec, struct rb_calling_info *calling, cons return vm_call0_cfunc_with_frame(ec, calling, argv); } +static void +vm_call_check_arity(struct rb_calling_info *calling, int argc, const VALUE *argv) +{ + if (calling->kw_splat && + calling->argc > 0 && + RB_TYPE_P(argv[calling->argc-1], T_HASH) && + RHASH_EMPTY_P(argv[calling->argc-1])) { + calling->argc--; + } + + rb_check_arity(calling->argc, argc, argc); +} + /* `ci' should point temporal value (on stack value) */ static VALUE vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const VALUE *argv) @@ -196,27 +209,13 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const ret = vm_call0_cfunc(ec, calling, argv); goto success; case VM_METHOD_TYPE_ATTRSET: - if (calling->kw_splat && - calling->argc > 0 && - RB_TYPE_P(argv[calling->argc-1], T_HASH) && - RHASH_EMPTY_P(argv[calling->argc-1])) { - calling->argc--; - } - - rb_check_arity(calling->argc, 1, 1); + vm_call_check_arity(calling, 1, argv); VM_CALL_METHOD_ATTR(ret, rb_ivar_set(calling->recv, vm_cc_cme(cc)->def->body.attr.id, argv[0]), (void)0); goto success; case VM_METHOD_TYPE_IVAR: - if (calling->kw_splat && - calling->argc > 0 && - RB_TYPE_P(argv[calling->argc-1], T_HASH) && - RHASH_EMPTY_P(argv[calling->argc-1])) { - calling->argc--; - } - - rb_check_arity(calling->argc, 0, 0); + vm_call_check_arity(calling, 0, argv); VM_CALL_METHOD_ATTR(ret, rb_attr_get(calling->recv, vm_cc_cme(cc)->def->body.attr.id), (void)0); @@ -274,6 +273,14 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const ret = rb_vm_invoke_proc(ec, proc, calling->argc, argv, calling->kw_splat, calling->block_handler); goto success; } + case OPTIMIZED_METHOD_TYPE_STRUCT_AREF: + vm_call_check_arity(calling, 0, argv); + ret = vm_call_opt_struct_aref0(ec, ec->cfp, 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); + goto success; default: rb_bug("vm_call0: unsupported optimized method type (%d)", vm_cc_cme(cc)->def->body.optimized.type); } |