From cc97a270080d2c6eb9dbdd2b9793ab549b6bb44d Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 3 Jun 2024 14:20:04 -0700 Subject: [PATCH] Add two new instructions for forwarding calls This commit adds `sendforward` and `invokesuperforward` for forwarding parameters to calls Co-authored-by: Matt Valentine-House --- compile.c | 25 ++- insns.def | 54 ++++-- prism_compile.c | 14 +- vm_args.c | 60 ++++--- vm_insnhelper.c | 20 ++- yjit/src/codegen.rs | 18 ++ yjit/src/cruby_bindings.inc.rs | 316 +++++++++++++++++---------------- 7 files changed, 301 insertions(+), 206 deletions(-) diff --git a/compile.c b/compile.c index 117a1f6e41..fee2fafc8d 100644 --- a/compile.c +++ b/compile.c @@ -1465,7 +1465,16 @@ new_insn_send(rb_iseq_t *iseq, int line_no, int node_id, ID id, VALUE argc, cons if (blockiseq) { RB_OBJ_WRITTEN(iseq, Qundef, blockiseq); } - INSN *insn = new_insn_core(iseq, line_no, node_id, BIN(send), 2, operands); + + INSN *insn; + + if (vm_ci_flag((struct rb_callinfo *)ci) & VM_CALL_FORWARDING) { + insn = new_insn_core(iseq, line_no, node_id, BIN(sendforward), 2, operands); + } + else { + insn = new_insn_core(iseq, line_no, node_id, BIN(send), 2, operands); + } + RB_OBJ_WRITTEN(iseq, Qundef, ci); RB_GC_GUARD(ci); return insn; @@ -8009,7 +8018,7 @@ compile_iter(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in INSN *iobj; LINK_ELEMENT *last_elem = LAST_ELEMENT(ret); iobj = IS_INSN(last_elem) ? (INSN*) last_elem : (INSN*) get_prev_insn((INSN*) last_elem); - while (INSN_OF(iobj) != BIN(send) && INSN_OF(iobj) != BIN(invokesuper)) { + while (!IS_INSN_ID(iobj, send) && !IS_INSN_ID(iobj, invokesuper) && !IS_INSN_ID(iobj, sendforward) && !IS_INSN_ID(iobj, invokesuperforward)) { iobj = (INSN*) get_prev_insn(iobj); } ELEM_INSERT_NEXT(&iobj->link, (LINK_ELEMENT*) retry_end_l); @@ -9607,9 +9616,15 @@ compile_super(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i if (type == NODE_ZSUPER) flag |= VM_CALL_ZSUPER; ADD_INSN(ret, node, putself); ADD_SEQ(ret, args); - ADD_INSN2(ret, node, invokesuper, - new_callinfo(iseq, 0, argc, flag, keywords, parent_block != NULL), - parent_block); + + const struct rb_callinfo * ci = new_callinfo(iseq, 0, argc, flag, keywords, parent_block != NULL); + + if (vm_ci_flag(ci) & VM_CALL_FORWARDING) { + ADD_INSN2(ret, node, invokesuperforward, ci, parent_block); + } + else { + ADD_INSN2(ret, node, invokesuper, ci, parent_block); + } if (popped) { ADD_INSN(ret, node, pop); diff --git a/insns.def b/insns.def index 6c96f252c2..d0a46969a8 100644 --- a/insns.def +++ b/insns.def @@ -866,21 +866,38 @@ send (VALUE val) // attr rb_snum_t sp_inc = sp_inc_of_sendish(cd->ci); // attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci); +{ + VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, false); + val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method); + JIT_EXEC(ec, val); + + if (UNDEF_P(val)) { + RESTORE_REGS(); + NEXT_INSN(); + } +} + +/* invoke forward method. */ +DEFINE_INSN +sendforward +(CALL_DATA cd, ISEQ blockiseq) +(...) +(VALUE val) +// attr rb_snum_t sp_inc = sp_inc_of_sendish(cd->ci); +// attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci); { struct rb_forwarding_call_data adjusted_cd; struct rb_callinfo adjusted_ci; CALL_DATA _cd = cd; - VALUE bh = vm_caller_setup_args(GET_EC(), GET_CFP(), &cd, blockiseq, 0, &adjusted_cd, &adjusted_ci); + VALUE bh = vm_caller_setup_fwd_args(GET_EC(), GET_CFP(), &cd, blockiseq, 0, &adjusted_cd, &adjusted_ci); val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method); JIT_EXEC(ec, val); - if (vm_ci_flag(_cd->ci) & VM_CALL_FORWARDING) { - if (_cd->cc != cd->cc && vm_cc_markable(cd->cc)) { - RB_OBJ_WRITE(GET_ISEQ(), &_cd->cc, cd->cc); - } + if (_cd->cc != cd->cc && vm_cc_markable(cd->cc)) { + RB_OBJ_WRITE(GET_ISEQ(), &_cd->cc, cd->cc); } if (UNDEF_P(val)) { @@ -1005,20 +1022,37 @@ invokesuper (VALUE val) // attr rb_snum_t sp_inc = sp_inc_of_sendish(cd->ci); // attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci); +{ + VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, true); + val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_super); + JIT_EXEC(ec, val); + + if (UNDEF_P(val)) { + RESTORE_REGS(); + NEXT_INSN(); + } +} + +/* super(args) # args.size => num */ +DEFINE_INSN +invokesuperforward +(CALL_DATA cd, ISEQ blockiseq) +(...) +(VALUE val) +// attr rb_snum_t sp_inc = sp_inc_of_sendish(cd->ci); +// attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci); { CALL_DATA _cd = cd; struct rb_forwarding_call_data adjusted_cd; struct rb_callinfo adjusted_ci; - VALUE bh = vm_caller_setup_args(GET_EC(), GET_CFP(), &cd, blockiseq, 1, &adjusted_cd, &adjusted_ci); + VALUE bh = vm_caller_setup_fwd_args(GET_EC(), GET_CFP(), &cd, blockiseq, 1, &adjusted_cd, &adjusted_ci); val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_super); JIT_EXEC(ec, val); - if (vm_ci_flag(_cd->ci) & VM_CALL_FORWARDING) { - if (_cd->cc != cd->cc && vm_cc_markable(cd->cc)) { - RB_OBJ_WRITE(GET_ISEQ(), &_cd->cc, cd->cc); - } + if (_cd->cc != cd->cc && vm_cc_markable(cd->cc)) { + RB_OBJ_WRITE(GET_ISEQ(), &_cd->cc, cd->cc); } if (UNDEF_P(val)) { diff --git a/prism_compile.c b/prism_compile.c index 9307b2449c..3aeb9d0e8e 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -2990,7 +2990,7 @@ pm_compile_retry_end_label(rb_iseq_t *iseq, LINK_ANCHOR *const ret, LABEL *retry INSN *iobj; LINK_ELEMENT *last_elem = LAST_ELEMENT(ret); iobj = IS_INSN(last_elem) ? (INSN*) last_elem : (INSN*) get_prev_insn((INSN*) last_elem); - while (INSN_OF(iobj) != BIN(send) && INSN_OF(iobj) != BIN(invokesuper)) { + while (!IS_INSN_ID(iobj, send) && !IS_INSN_ID(iobj, invokesuper) && !IS_INSN_ID(iobj, sendforward) && !IS_INSN_ID(iobj, invokesuperforward)) { iobj = (INSN*) get_prev_insn(iobj); } ELEM_INSERT_NEXT(&iobj->link, (LINK_ELEMENT*) retry_end_l); @@ -6707,7 +6707,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, flag |= VM_CALL_FORWARDING; pm_local_index_t mult_local = pm_lookup_local_index(iseq, scope_node, PM_CONSTANT_DOT3, 0); PUSH_GETLOCAL(ret, location, mult_local.index, mult_local.level); - PUSH_INSN2(ret, location, invokesuper, new_callinfo(iseq, 0, 0, flag, NULL, block != NULL), block); + PUSH_INSN2(ret, location, invokesuperforward, new_callinfo(iseq, 0, 0, flag, NULL, block != NULL), block); if (popped) PUSH_INSN(ret, location, pop); return; } @@ -9277,8 +9277,14 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } PUSH_SEQ(ret, args); - PUSH_INSN2(ret, location, invokesuper, new_callinfo(iseq, 0, argc, flags, keywords, current_block != NULL), current_block); - pm_compile_retry_end_label(iseq, ret, retry_end_l); + if (ISEQ_BODY(ISEQ_BODY(iseq)->local_iseq)->param.flags.forwardable) { + flags |= VM_CALL_FORWARDING; + PUSH_INSN2(ret, location, invokesuperforward, new_callinfo(iseq, 0, argc, flags, keywords, current_block != NULL), current_block); + } + else { + PUSH_INSN2(ret, location, invokesuper, new_callinfo(iseq, 0, argc, flags, keywords, current_block != NULL), current_block); + pm_compile_retry_end_label(iseq, ret, retry_end_l); + } if (popped) PUSH_INSN(ret, location, pop); ISEQ_COMPILE_DATA(iseq)->current_block = previous_block; diff --git a/vm_args.c b/vm_args.c index 6d31187ea4..4d35b00e4a 100644 --- a/vm_args.c +++ b/vm_args.c @@ -1061,52 +1061,54 @@ vm_caller_setup_arg_block(const rb_execution_context_t *ec, rb_control_frame_t * static void vm_adjust_stack_forwarding(const struct rb_execution_context_struct *ec, struct rb_control_frame_struct *cfp, CALL_INFO callers_info, VALUE splat); static VALUE -vm_caller_setup_args(const rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, +vm_caller_setup_fwd_args(const rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_DATA *cd, const rb_iseq_t *blockiseq, const int is_super, struct rb_forwarding_call_data *adjusted_cd, struct rb_callinfo *adjusted_ci) { CALL_INFO site_ci = (*cd)->ci; VALUE bh = Qundef; - if (vm_ci_flag(site_ci) & VM_CALL_FORWARDING) { - RUBY_ASSERT(ISEQ_BODY(ISEQ_BODY(GET_ISEQ())->local_iseq)->param.flags.forwardable); - CALL_INFO caller_ci = (CALL_INFO)TOPN(0); + RUBY_ASSERT(ISEQ_BODY(ISEQ_BODY(GET_ISEQ())->local_iseq)->param.flags.forwardable); + CALL_INFO caller_ci = (CALL_INFO)TOPN(0); - unsigned int forwarding_argc = vm_ci_argc(site_ci); - VALUE splat = Qfalse; + unsigned int forwarding_argc = vm_ci_argc(site_ci); + VALUE splat = Qfalse; - if (vm_ci_flag(site_ci) & VM_CALL_ARGS_SPLAT) { - // If we're called with args_splat, the top 1 should be an array - splat = TOPN(1); - forwarding_argc += (RARRAY_LEN(splat) - 1); - } + if (vm_ci_flag(site_ci) & VM_CALL_ARGS_SPLAT) { + // If we're called with args_splat, the top 1 should be an array + splat = TOPN(1); + forwarding_argc += (RARRAY_LEN(splat) - 1); + } - // Need to setup the block in case of e.g. `super { :block }` - if (is_super && blockiseq) { - bh = vm_caller_setup_arg_block(ec, GET_CFP(), site_ci, blockiseq, is_super); - } - else { - bh = VM_ENV_BLOCK_HANDLER(GET_LEP()); - } + // Need to setup the block in case of e.g. `super { :block }` + if (is_super && blockiseq) { + bh = vm_caller_setup_arg_block(ec, GET_CFP(), site_ci, blockiseq, is_super); + } + else { + bh = VM_ENV_BLOCK_HANDLER(GET_LEP()); + } - vm_adjust_stack_forwarding(ec, GET_CFP(), caller_ci, splat); + vm_adjust_stack_forwarding(ec, GET_CFP(), caller_ci, splat); - *adjusted_ci = VM_CI_ON_STACK( + *adjusted_ci = VM_CI_ON_STACK( vm_ci_mid(site_ci), (vm_ci_flag(caller_ci) | (vm_ci_flag(site_ci) & (VM_CALL_FCALL | VM_CALL_FORWARDING))), forwarding_argc + vm_ci_argc(caller_ci), vm_ci_kwarg(caller_ci) - ); + ); - adjusted_cd->cd.ci = adjusted_ci; - adjusted_cd->cd.cc = (*cd)->cc; - adjusted_cd->caller_ci = caller_ci; + adjusted_cd->cd.ci = adjusted_ci; + adjusted_cd->cd.cc = (*cd)->cc; + adjusted_cd->caller_ci = caller_ci; - *cd = &adjusted_cd->cd; - } - else { - bh = vm_caller_setup_arg_block(ec, GET_CFP(), site_ci, blockiseq, is_super); - } + *cd = &adjusted_cd->cd; return bh; } + +static VALUE +vm_caller_setup_args(const rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, + CALL_DATA *cd, const rb_iseq_t *blockiseq, const int is_super) +{ + return vm_caller_setup_arg_block(ec, GET_CFP(), (*cd)->ci, blockiseq, is_super); +} diff --git a/vm_insnhelper.c b/vm_insnhelper.c index a3352c8b20..c65520a940 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -5929,7 +5929,15 @@ rb_vm_send(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_DATA cd struct rb_callinfo adjusted_ci; CALL_DATA _cd = cd; - VALUE bh = vm_caller_setup_args(ec, GET_CFP(), &cd, blockiseq, false, &adjusted_cd, &adjusted_ci); + VALUE bh; + + if (vm_ci_flag(_cd->ci) & VM_CALL_FORWARDING) { + bh = vm_caller_setup_fwd_args(GET_EC(), GET_CFP(), &cd, blockiseq, false, &adjusted_cd, &adjusted_ci); + } + else { + bh = vm_caller_setup_args(ec, GET_CFP(), &cd, blockiseq, false); + } + VALUE val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method); if (vm_ci_flag(_cd->ci) & VM_CALL_FORWARDING) { @@ -5960,7 +5968,15 @@ rb_vm_invokesuper(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_ struct rb_callinfo adjusted_ci; CALL_DATA _cd = cd; - VALUE bh = vm_caller_setup_args(ec, GET_CFP(), &cd, blockiseq, true, &adjusted_cd, &adjusted_ci); + VALUE bh; + + if (vm_ci_flag(_cd->ci) & VM_CALL_FORWARDING) { + bh = vm_caller_setup_fwd_args(ec, GET_CFP(), &cd, blockiseq, true, &adjusted_cd, &adjusted_ci); + } + else { + bh = vm_caller_setup_args(ec, GET_CFP(), &cd, blockiseq, true); + } + VALUE val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_super); if (vm_ci_flag(_cd->ci) & VM_CALL_FORWARDING) { diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 26234aec41..961d6438e3 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -9070,6 +9070,14 @@ fn gen_send( }) } +fn gen_sendforward( + jit: &mut JITState, + asm: &mut Assembler, + ocb: &mut OutlinedCb, +) -> Option { + return gen_send(jit, asm, ocb); +} + fn gen_invokeblock( jit: &mut JITState, asm: &mut Assembler, @@ -9253,6 +9261,14 @@ fn gen_invokesuper( }) } +fn gen_invokesuperforward( + jit: &mut JITState, + asm: &mut Assembler, + ocb: &mut OutlinedCb, +) -> Option { + return gen_invokesuper(jit, asm, ocb); +} + fn gen_invokesuper_specialized( jit: &mut JITState, asm: &mut Assembler, @@ -10232,8 +10248,10 @@ fn get_gen_fn(opcode: VALUE) -> Option { YARVINSN_getblockparam => Some(gen_getblockparam), YARVINSN_opt_send_without_block => Some(gen_opt_send_without_block), YARVINSN_send => Some(gen_send), + YARVINSN_sendforward => Some(gen_sendforward), YARVINSN_invokeblock => Some(gen_invokeblock), YARVINSN_invokesuper => Some(gen_invokesuper), + YARVINSN_invokesuperforward => Some(gen_invokesuperforward), YARVINSN_leave => Some(gen_leave), YARVINSN_getglobal => Some(gen_getglobal), diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index 994fef28b7..cbe635f060 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -775,162 +775,166 @@ pub const YARVINSN_defineclass: ruby_vminsn_type = 53; pub const YARVINSN_definemethod: ruby_vminsn_type = 54; pub const YARVINSN_definesmethod: ruby_vminsn_type = 55; pub const YARVINSN_send: ruby_vminsn_type = 56; -pub const YARVINSN_opt_send_without_block: ruby_vminsn_type = 57; -pub const YARVINSN_objtostring: ruby_vminsn_type = 58; -pub const YARVINSN_opt_str_freeze: ruby_vminsn_type = 59; -pub const YARVINSN_opt_nil_p: ruby_vminsn_type = 60; -pub const YARVINSN_opt_str_uminus: ruby_vminsn_type = 61; -pub const YARVINSN_opt_newarray_send: ruby_vminsn_type = 62; -pub const YARVINSN_invokesuper: ruby_vminsn_type = 63; -pub const YARVINSN_invokeblock: ruby_vminsn_type = 64; -pub const YARVINSN_leave: ruby_vminsn_type = 65; -pub const YARVINSN_throw: ruby_vminsn_type = 66; -pub const YARVINSN_jump: ruby_vminsn_type = 67; -pub const YARVINSN_branchif: ruby_vminsn_type = 68; -pub const YARVINSN_branchunless: ruby_vminsn_type = 69; -pub const YARVINSN_branchnil: ruby_vminsn_type = 70; -pub const YARVINSN_once: ruby_vminsn_type = 71; -pub const YARVINSN_opt_case_dispatch: ruby_vminsn_type = 72; -pub const YARVINSN_opt_plus: ruby_vminsn_type = 73; -pub const YARVINSN_opt_minus: ruby_vminsn_type = 74; -pub const YARVINSN_opt_mult: ruby_vminsn_type = 75; -pub const YARVINSN_opt_div: ruby_vminsn_type = 76; -pub const YARVINSN_opt_mod: ruby_vminsn_type = 77; -pub const YARVINSN_opt_eq: ruby_vminsn_type = 78; -pub const YARVINSN_opt_neq: ruby_vminsn_type = 79; -pub const YARVINSN_opt_lt: ruby_vminsn_type = 80; -pub const YARVINSN_opt_le: ruby_vminsn_type = 81; -pub const YARVINSN_opt_gt: ruby_vminsn_type = 82; -pub const YARVINSN_opt_ge: ruby_vminsn_type = 83; -pub const YARVINSN_opt_ltlt: ruby_vminsn_type = 84; -pub const YARVINSN_opt_and: ruby_vminsn_type = 85; -pub const YARVINSN_opt_or: ruby_vminsn_type = 86; -pub const YARVINSN_opt_aref: ruby_vminsn_type = 87; -pub const YARVINSN_opt_aset: ruby_vminsn_type = 88; -pub const YARVINSN_opt_aset_with: ruby_vminsn_type = 89; -pub const YARVINSN_opt_aref_with: ruby_vminsn_type = 90; -pub const YARVINSN_opt_length: ruby_vminsn_type = 91; -pub const YARVINSN_opt_size: ruby_vminsn_type = 92; -pub const YARVINSN_opt_empty_p: ruby_vminsn_type = 93; -pub const YARVINSN_opt_succ: ruby_vminsn_type = 94; -pub const YARVINSN_opt_not: ruby_vminsn_type = 95; -pub const YARVINSN_opt_regexpmatch2: ruby_vminsn_type = 96; -pub const YARVINSN_invokebuiltin: ruby_vminsn_type = 97; -pub const YARVINSN_opt_invokebuiltin_delegate: ruby_vminsn_type = 98; -pub const YARVINSN_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 99; -pub const YARVINSN_getlocal_WC_0: ruby_vminsn_type = 100; -pub const YARVINSN_getlocal_WC_1: ruby_vminsn_type = 101; -pub const YARVINSN_setlocal_WC_0: ruby_vminsn_type = 102; -pub const YARVINSN_setlocal_WC_1: ruby_vminsn_type = 103; -pub const YARVINSN_putobject_INT2FIX_0_: ruby_vminsn_type = 104; -pub const YARVINSN_putobject_INT2FIX_1_: ruby_vminsn_type = 105; -pub const YARVINSN_trace_nop: ruby_vminsn_type = 106; -pub const YARVINSN_trace_getlocal: ruby_vminsn_type = 107; -pub const YARVINSN_trace_setlocal: ruby_vminsn_type = 108; -pub const YARVINSN_trace_getblockparam: ruby_vminsn_type = 109; -pub const YARVINSN_trace_setblockparam: ruby_vminsn_type = 110; -pub const YARVINSN_trace_getblockparamproxy: ruby_vminsn_type = 111; -pub const YARVINSN_trace_getspecial: ruby_vminsn_type = 112; -pub const YARVINSN_trace_setspecial: ruby_vminsn_type = 113; -pub const YARVINSN_trace_getinstancevariable: ruby_vminsn_type = 114; -pub const YARVINSN_trace_setinstancevariable: ruby_vminsn_type = 115; -pub const YARVINSN_trace_getclassvariable: ruby_vminsn_type = 116; -pub const YARVINSN_trace_setclassvariable: ruby_vminsn_type = 117; -pub const YARVINSN_trace_opt_getconstant_path: ruby_vminsn_type = 118; -pub const YARVINSN_trace_getconstant: ruby_vminsn_type = 119; -pub const YARVINSN_trace_setconstant: ruby_vminsn_type = 120; -pub const YARVINSN_trace_getglobal: ruby_vminsn_type = 121; -pub const YARVINSN_trace_setglobal: ruby_vminsn_type = 122; -pub const YARVINSN_trace_putnil: ruby_vminsn_type = 123; -pub const YARVINSN_trace_putself: ruby_vminsn_type = 124; -pub const YARVINSN_trace_putobject: ruby_vminsn_type = 125; -pub const YARVINSN_trace_putspecialobject: ruby_vminsn_type = 126; -pub const YARVINSN_trace_putstring: ruby_vminsn_type = 127; -pub const YARVINSN_trace_putchilledstring: ruby_vminsn_type = 128; -pub const YARVINSN_trace_concatstrings: ruby_vminsn_type = 129; -pub const YARVINSN_trace_anytostring: ruby_vminsn_type = 130; -pub const YARVINSN_trace_toregexp: ruby_vminsn_type = 131; -pub const YARVINSN_trace_intern: ruby_vminsn_type = 132; -pub const YARVINSN_trace_newarray: ruby_vminsn_type = 133; -pub const YARVINSN_trace_newarraykwsplat: ruby_vminsn_type = 134; -pub const YARVINSN_trace_pushtoarraykwsplat: ruby_vminsn_type = 135; -pub const YARVINSN_trace_duparray: ruby_vminsn_type = 136; -pub const YARVINSN_trace_duphash: ruby_vminsn_type = 137; -pub const YARVINSN_trace_expandarray: ruby_vminsn_type = 138; -pub const YARVINSN_trace_concatarray: ruby_vminsn_type = 139; -pub const YARVINSN_trace_concattoarray: ruby_vminsn_type = 140; -pub const YARVINSN_trace_pushtoarray: ruby_vminsn_type = 141; -pub const YARVINSN_trace_splatarray: ruby_vminsn_type = 142; -pub const YARVINSN_trace_splatkw: ruby_vminsn_type = 143; -pub const YARVINSN_trace_newhash: ruby_vminsn_type = 144; -pub const YARVINSN_trace_newrange: ruby_vminsn_type = 145; -pub const YARVINSN_trace_pop: ruby_vminsn_type = 146; -pub const YARVINSN_trace_dup: ruby_vminsn_type = 147; -pub const YARVINSN_trace_dupn: ruby_vminsn_type = 148; -pub const YARVINSN_trace_swap: ruby_vminsn_type = 149; -pub const YARVINSN_trace_opt_reverse: ruby_vminsn_type = 150; -pub const YARVINSN_trace_topn: ruby_vminsn_type = 151; -pub const YARVINSN_trace_setn: ruby_vminsn_type = 152; -pub const YARVINSN_trace_adjuststack: ruby_vminsn_type = 153; -pub const YARVINSN_trace_defined: ruby_vminsn_type = 154; -pub const YARVINSN_trace_definedivar: ruby_vminsn_type = 155; -pub const YARVINSN_trace_checkmatch: ruby_vminsn_type = 156; -pub const YARVINSN_trace_checkkeyword: ruby_vminsn_type = 157; -pub const YARVINSN_trace_checktype: ruby_vminsn_type = 158; -pub const YARVINSN_trace_defineclass: ruby_vminsn_type = 159; -pub const YARVINSN_trace_definemethod: ruby_vminsn_type = 160; -pub const YARVINSN_trace_definesmethod: ruby_vminsn_type = 161; -pub const YARVINSN_trace_send: ruby_vminsn_type = 162; -pub const YARVINSN_trace_opt_send_without_block: ruby_vminsn_type = 163; -pub const YARVINSN_trace_objtostring: ruby_vminsn_type = 164; -pub const YARVINSN_trace_opt_str_freeze: ruby_vminsn_type = 165; -pub const YARVINSN_trace_opt_nil_p: ruby_vminsn_type = 166; -pub const YARVINSN_trace_opt_str_uminus: ruby_vminsn_type = 167; -pub const YARVINSN_trace_opt_newarray_send: ruby_vminsn_type = 168; -pub const YARVINSN_trace_invokesuper: ruby_vminsn_type = 169; -pub const YARVINSN_trace_invokeblock: ruby_vminsn_type = 170; -pub const YARVINSN_trace_leave: ruby_vminsn_type = 171; -pub const YARVINSN_trace_throw: ruby_vminsn_type = 172; -pub const YARVINSN_trace_jump: ruby_vminsn_type = 173; -pub const YARVINSN_trace_branchif: ruby_vminsn_type = 174; -pub const YARVINSN_trace_branchunless: ruby_vminsn_type = 175; -pub const YARVINSN_trace_branchnil: ruby_vminsn_type = 176; -pub const YARVINSN_trace_once: ruby_vminsn_type = 177; -pub const YARVINSN_trace_opt_case_dispatch: ruby_vminsn_type = 178; -pub const YARVINSN_trace_opt_plus: ruby_vminsn_type = 179; -pub const YARVINSN_trace_opt_minus: ruby_vminsn_type = 180; -pub const YARVINSN_trace_opt_mult: ruby_vminsn_type = 181; -pub const YARVINSN_trace_opt_div: ruby_vminsn_type = 182; -pub const YARVINSN_trace_opt_mod: ruby_vminsn_type = 183; -pub const YARVINSN_trace_opt_eq: ruby_vminsn_type = 184; -pub const YARVINSN_trace_opt_neq: ruby_vminsn_type = 185; -pub const YARVINSN_trace_opt_lt: ruby_vminsn_type = 186; -pub const YARVINSN_trace_opt_le: ruby_vminsn_type = 187; -pub const YARVINSN_trace_opt_gt: ruby_vminsn_type = 188; -pub const YARVINSN_trace_opt_ge: ruby_vminsn_type = 189; -pub const YARVINSN_trace_opt_ltlt: ruby_vminsn_type = 190; -pub const YARVINSN_trace_opt_and: ruby_vminsn_type = 191; -pub const YARVINSN_trace_opt_or: ruby_vminsn_type = 192; -pub const YARVINSN_trace_opt_aref: ruby_vminsn_type = 193; -pub const YARVINSN_trace_opt_aset: ruby_vminsn_type = 194; -pub const YARVINSN_trace_opt_aset_with: ruby_vminsn_type = 195; -pub const YARVINSN_trace_opt_aref_with: ruby_vminsn_type = 196; -pub const YARVINSN_trace_opt_length: ruby_vminsn_type = 197; -pub const YARVINSN_trace_opt_size: ruby_vminsn_type = 198; -pub const YARVINSN_trace_opt_empty_p: ruby_vminsn_type = 199; -pub const YARVINSN_trace_opt_succ: ruby_vminsn_type = 200; -pub const YARVINSN_trace_opt_not: ruby_vminsn_type = 201; -pub const YARVINSN_trace_opt_regexpmatch2: ruby_vminsn_type = 202; -pub const YARVINSN_trace_invokebuiltin: ruby_vminsn_type = 203; -pub const YARVINSN_trace_opt_invokebuiltin_delegate: ruby_vminsn_type = 204; -pub const YARVINSN_trace_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 205; -pub const YARVINSN_trace_getlocal_WC_0: ruby_vminsn_type = 206; -pub const YARVINSN_trace_getlocal_WC_1: ruby_vminsn_type = 207; -pub const YARVINSN_trace_setlocal_WC_0: ruby_vminsn_type = 208; -pub const YARVINSN_trace_setlocal_WC_1: ruby_vminsn_type = 209; -pub const YARVINSN_trace_putobject_INT2FIX_0_: ruby_vminsn_type = 210; -pub const YARVINSN_trace_putobject_INT2FIX_1_: ruby_vminsn_type = 211; -pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 212; +pub const YARVINSN_sendforward: ruby_vminsn_type = 57; +pub const YARVINSN_opt_send_without_block: ruby_vminsn_type = 58; +pub const YARVINSN_objtostring: ruby_vminsn_type = 59; +pub const YARVINSN_opt_str_freeze: ruby_vminsn_type = 60; +pub const YARVINSN_opt_nil_p: ruby_vminsn_type = 61; +pub const YARVINSN_opt_str_uminus: ruby_vminsn_type = 62; +pub const YARVINSN_opt_newarray_send: ruby_vminsn_type = 63; +pub const YARVINSN_invokesuper: ruby_vminsn_type = 64; +pub const YARVINSN_invokesuperforward: ruby_vminsn_type = 65; +pub const YARVINSN_invokeblock: ruby_vminsn_type = 66; +pub const YARVINSN_leave: ruby_vminsn_type = 67; +pub const YARVINSN_throw: ruby_vminsn_type = 68; +pub const YARVINSN_jump: ruby_vminsn_type = 69; +pub const YARVINSN_branchif: ruby_vminsn_type = 70; +pub const YARVINSN_branchunless: ruby_vminsn_type = 71; +pub const YARVINSN_branchnil: ruby_vminsn_type = 72; +pub const YARVINSN_once: ruby_vminsn_type = 73; +pub const YARVINSN_opt_case_dispatch: ruby_vminsn_type = 74; +pub const YARVINSN_opt_plus: ruby_vminsn_type = 75; +pub const YARVINSN_opt_minus: ruby_vminsn_type = 76; +pub const YARVINSN_opt_mult: ruby_vminsn_type = 77; +pub const YARVINSN_opt_div: ruby_vminsn_type = 78; +pub const YARVINSN_opt_mod: ruby_vminsn_type = 79; +pub const YARVINSN_opt_eq: ruby_vminsn_type = 80; +pub const YARVINSN_opt_neq: ruby_vminsn_type = 81; +pub const YARVINSN_opt_lt: ruby_vminsn_type = 82; +pub const YARVINSN_opt_le: ruby_vminsn_type = 83; +pub const YARVINSN_opt_gt: ruby_vminsn_type = 84; +pub const YARVINSN_opt_ge: ruby_vminsn_type = 85; +pub const YARVINSN_opt_ltlt: ruby_vminsn_type = 86; +pub const YARVINSN_opt_and: ruby_vminsn_type = 87; +pub const YARVINSN_opt_or: ruby_vminsn_type = 88; +pub const YARVINSN_opt_aref: ruby_vminsn_type = 89; +pub const YARVINSN_opt_aset: ruby_vminsn_type = 90; +pub const YARVINSN_opt_aset_with: ruby_vminsn_type = 91; +pub const YARVINSN_opt_aref_with: ruby_vminsn_type = 92; +pub const YARVINSN_opt_length: ruby_vminsn_type = 93; +pub const YARVINSN_opt_size: ruby_vminsn_type = 94; +pub const YARVINSN_opt_empty_p: ruby_vminsn_type = 95; +pub const YARVINSN_opt_succ: ruby_vminsn_type = 96; +pub const YARVINSN_opt_not: ruby_vminsn_type = 97; +pub const YARVINSN_opt_regexpmatch2: ruby_vminsn_type = 98; +pub const YARVINSN_invokebuiltin: ruby_vminsn_type = 99; +pub const YARVINSN_opt_invokebuiltin_delegate: ruby_vminsn_type = 100; +pub const YARVINSN_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 101; +pub const YARVINSN_getlocal_WC_0: ruby_vminsn_type = 102; +pub const YARVINSN_getlocal_WC_1: ruby_vminsn_type = 103; +pub const YARVINSN_setlocal_WC_0: ruby_vminsn_type = 104; +pub const YARVINSN_setlocal_WC_1: ruby_vminsn_type = 105; +pub const YARVINSN_putobject_INT2FIX_0_: ruby_vminsn_type = 106; +pub const YARVINSN_putobject_INT2FIX_1_: ruby_vminsn_type = 107; +pub const YARVINSN_trace_nop: ruby_vminsn_type = 108; +pub const YARVINSN_trace_getlocal: ruby_vminsn_type = 109; +pub const YARVINSN_trace_setlocal: ruby_vminsn_type = 110; +pub const YARVINSN_trace_getblockparam: ruby_vminsn_type = 111; +pub const YARVINSN_trace_setblockparam: ruby_vminsn_type = 112; +pub const YARVINSN_trace_getblockparamproxy: ruby_vminsn_type = 113; +pub const YARVINSN_trace_getspecial: ruby_vminsn_type = 114; +pub const YARVINSN_trace_setspecial: ruby_vminsn_type = 115; +pub const YARVINSN_trace_getinstancevariable: ruby_vminsn_type = 116; +pub const YARVINSN_trace_setinstancevariable: ruby_vminsn_type = 117; +pub const YARVINSN_trace_getclassvariable: ruby_vminsn_type = 118; +pub const YARVINSN_trace_setclassvariable: ruby_vminsn_type = 119; +pub const YARVINSN_trace_opt_getconstant_path: ruby_vminsn_type = 120; +pub const YARVINSN_trace_getconstant: ruby_vminsn_type = 121; +pub const YARVINSN_trace_setconstant: ruby_vminsn_type = 122; +pub const YARVINSN_trace_getglobal: ruby_vminsn_type = 123; +pub const YARVINSN_trace_setglobal: ruby_vminsn_type = 124; +pub const YARVINSN_trace_putnil: ruby_vminsn_type = 125; +pub const YARVINSN_trace_putself: ruby_vminsn_type = 126; +pub const YARVINSN_trace_putobject: ruby_vminsn_type = 127; +pub const YARVINSN_trace_putspecialobject: ruby_vminsn_type = 128; +pub const YARVINSN_trace_putstring: ruby_vminsn_type = 129; +pub const YARVINSN_trace_putchilledstring: ruby_vminsn_type = 130; +pub const YARVINSN_trace_concatstrings: ruby_vminsn_type = 131; +pub const YARVINSN_trace_anytostring: ruby_vminsn_type = 132; +pub const YARVINSN_trace_toregexp: ruby_vminsn_type = 133; +pub const YARVINSN_trace_intern: ruby_vminsn_type = 134; +pub const YARVINSN_trace_newarray: ruby_vminsn_type = 135; +pub const YARVINSN_trace_newarraykwsplat: ruby_vminsn_type = 136; +pub const YARVINSN_trace_pushtoarraykwsplat: ruby_vminsn_type = 137; +pub const YARVINSN_trace_duparray: ruby_vminsn_type = 138; +pub const YARVINSN_trace_duphash: ruby_vminsn_type = 139; +pub const YARVINSN_trace_expandarray: ruby_vminsn_type = 140; +pub const YARVINSN_trace_concatarray: ruby_vminsn_type = 141; +pub const YARVINSN_trace_concattoarray: ruby_vminsn_type = 142; +pub const YARVINSN_trace_pushtoarray: ruby_vminsn_type = 143; +pub const YARVINSN_trace_splatarray: ruby_vminsn_type = 144; +pub const YARVINSN_trace_splatkw: ruby_vminsn_type = 145; +pub const YARVINSN_trace_newhash: ruby_vminsn_type = 146; +pub const YARVINSN_trace_newrange: ruby_vminsn_type = 147; +pub const YARVINSN_trace_pop: ruby_vminsn_type = 148; +pub const YARVINSN_trace_dup: ruby_vminsn_type = 149; +pub const YARVINSN_trace_dupn: ruby_vminsn_type = 150; +pub const YARVINSN_trace_swap: ruby_vminsn_type = 151; +pub const YARVINSN_trace_opt_reverse: ruby_vminsn_type = 152; +pub const YARVINSN_trace_topn: ruby_vminsn_type = 153; +pub const YARVINSN_trace_setn: ruby_vminsn_type = 154; +pub const YARVINSN_trace_adjuststack: ruby_vminsn_type = 155; +pub const YARVINSN_trace_defined: ruby_vminsn_type = 156; +pub const YARVINSN_trace_definedivar: ruby_vminsn_type = 157; +pub const YARVINSN_trace_checkmatch: ruby_vminsn_type = 158; +pub const YARVINSN_trace_checkkeyword: ruby_vminsn_type = 159; +pub const YARVINSN_trace_checktype: ruby_vminsn_type = 160; +pub const YARVINSN_trace_defineclass: ruby_vminsn_type = 161; +pub const YARVINSN_trace_definemethod: ruby_vminsn_type = 162; +pub const YARVINSN_trace_definesmethod: ruby_vminsn_type = 163; +pub const YARVINSN_trace_send: ruby_vminsn_type = 164; +pub const YARVINSN_trace_sendforward: ruby_vminsn_type = 165; +pub const YARVINSN_trace_opt_send_without_block: ruby_vminsn_type = 166; +pub const YARVINSN_trace_objtostring: ruby_vminsn_type = 167; +pub const YARVINSN_trace_opt_str_freeze: ruby_vminsn_type = 168; +pub const YARVINSN_trace_opt_nil_p: ruby_vminsn_type = 169; +pub const YARVINSN_trace_opt_str_uminus: ruby_vminsn_type = 170; +pub const YARVINSN_trace_opt_newarray_send: ruby_vminsn_type = 171; +pub const YARVINSN_trace_invokesuper: ruby_vminsn_type = 172; +pub const YARVINSN_trace_invokesuperforward: ruby_vminsn_type = 173; +pub const YARVINSN_trace_invokeblock: ruby_vminsn_type = 174; +pub const YARVINSN_trace_leave: ruby_vminsn_type = 175; +pub const YARVINSN_trace_throw: ruby_vminsn_type = 176; +pub const YARVINSN_trace_jump: ruby_vminsn_type = 177; +pub const YARVINSN_trace_branchif: ruby_vminsn_type = 178; +pub const YARVINSN_trace_branchunless: ruby_vminsn_type = 179; +pub const YARVINSN_trace_branchnil: ruby_vminsn_type = 180; +pub const YARVINSN_trace_once: ruby_vminsn_type = 181; +pub const YARVINSN_trace_opt_case_dispatch: ruby_vminsn_type = 182; +pub const YARVINSN_trace_opt_plus: ruby_vminsn_type = 183; +pub const YARVINSN_trace_opt_minus: ruby_vminsn_type = 184; +pub const YARVINSN_trace_opt_mult: ruby_vminsn_type = 185; +pub const YARVINSN_trace_opt_div: ruby_vminsn_type = 186; +pub const YARVINSN_trace_opt_mod: ruby_vminsn_type = 187; +pub const YARVINSN_trace_opt_eq: ruby_vminsn_type = 188; +pub const YARVINSN_trace_opt_neq: ruby_vminsn_type = 189; +pub const YARVINSN_trace_opt_lt: ruby_vminsn_type = 190; +pub const YARVINSN_trace_opt_le: ruby_vminsn_type = 191; +pub const YARVINSN_trace_opt_gt: ruby_vminsn_type = 192; +pub const YARVINSN_trace_opt_ge: ruby_vminsn_type = 193; +pub const YARVINSN_trace_opt_ltlt: ruby_vminsn_type = 194; +pub const YARVINSN_trace_opt_and: ruby_vminsn_type = 195; +pub const YARVINSN_trace_opt_or: ruby_vminsn_type = 196; +pub const YARVINSN_trace_opt_aref: ruby_vminsn_type = 197; +pub const YARVINSN_trace_opt_aset: ruby_vminsn_type = 198; +pub const YARVINSN_trace_opt_aset_with: ruby_vminsn_type = 199; +pub const YARVINSN_trace_opt_aref_with: ruby_vminsn_type = 200; +pub const YARVINSN_trace_opt_length: ruby_vminsn_type = 201; +pub const YARVINSN_trace_opt_size: ruby_vminsn_type = 202; +pub const YARVINSN_trace_opt_empty_p: ruby_vminsn_type = 203; +pub const YARVINSN_trace_opt_succ: ruby_vminsn_type = 204; +pub const YARVINSN_trace_opt_not: ruby_vminsn_type = 205; +pub const YARVINSN_trace_opt_regexpmatch2: ruby_vminsn_type = 206; +pub const YARVINSN_trace_invokebuiltin: ruby_vminsn_type = 207; +pub const YARVINSN_trace_opt_invokebuiltin_delegate: ruby_vminsn_type = 208; +pub const YARVINSN_trace_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 209; +pub const YARVINSN_trace_getlocal_WC_0: ruby_vminsn_type = 210; +pub const YARVINSN_trace_getlocal_WC_1: ruby_vminsn_type = 211; +pub const YARVINSN_trace_setlocal_WC_0: ruby_vminsn_type = 212; +pub const YARVINSN_trace_setlocal_WC_1: ruby_vminsn_type = 213; +pub const YARVINSN_trace_putobject_INT2FIX_0_: ruby_vminsn_type = 214; +pub const YARVINSN_trace_putobject_INT2FIX_1_: ruby_vminsn_type = 215; +pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 216; pub type ruby_vminsn_type = u32; pub type rb_iseq_callback = ::std::option::Option< unsafe extern "C" fn(arg1: *const rb_iseq_t, arg2: *mut ::std::os::raw::c_void),