diff options
| -rw-r--r-- | zjit/src/codegen.rs | 9 | ||||
| -rw-r--r-- | zjit/src/cruby.rs | 37 | ||||
| -rw-r--r-- | zjit/src/hir.rs | 39 |
3 files changed, 45 insertions, 40 deletions
diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs index 082db3fae4..d00ab500d7 100644 --- a/zjit/src/codegen.rs +++ b/zjit/src/codegen.rs @@ -1293,10 +1293,11 @@ fn gen_send_without_block_direct( let mut c_args = vec![recv]; c_args.extend(&args); - let num_optionals_passed = if unsafe { get_iseq_flags_has_opt(iseq) } { + let params = unsafe { iseq.params() }; + let num_optionals_passed = if params.flags.has_opt() != 0 { // See vm_call_iseq_setup_normal_opt_start in vm_inshelper.c - let lead_num = unsafe { get_iseq_body_param_lead_num(iseq) } as u32; - let opt_num = unsafe { get_iseq_body_param_opt_num(iseq) } as u32; + let lead_num = params.lead_num as u32; + let opt_num = params.opt_num as u32; assert!(args.len() as u32 <= lead_num + opt_num); let num_optionals_passed = args.len() as u32 - lead_num; num_optionals_passed @@ -2212,7 +2213,7 @@ c_callable! { // Fill nils to uninitialized (non-argument) locals let local_size = get_iseq_body_local_table_size(iseq).to_usize(); - let num_params = get_iseq_body_param_size(iseq).to_usize(); + let num_params = iseq.params().size.to_usize(); let base = sp.offset(-local_size_and_idx_to_bp_offset(local_size, num_params) as isize); slice::from_raw_parts_mut(base, local_size - num_params).fill(Qnil); } diff --git a/zjit/src/cruby.rs b/zjit/src/cruby.rs index 771f256037..443ed0d86e 100644 --- a/zjit/src/cruby.rs +++ b/zjit/src/cruby.rs @@ -192,21 +192,7 @@ pub use rb_get_iseq_body_local_iseq as get_iseq_body_local_iseq; pub use rb_get_iseq_body_iseq_encoded as get_iseq_body_iseq_encoded; pub use rb_get_iseq_body_stack_max as get_iseq_body_stack_max; pub use rb_get_iseq_body_type as get_iseq_body_type; -pub use rb_get_iseq_flags_has_lead as get_iseq_flags_has_lead; -pub use rb_get_iseq_flags_has_opt as get_iseq_flags_has_opt; -pub use rb_get_iseq_flags_has_kw as get_iseq_flags_has_kw; -pub use rb_get_iseq_flags_has_rest as get_iseq_flags_has_rest; -pub use rb_get_iseq_flags_has_post as get_iseq_flags_has_post; -pub use rb_get_iseq_flags_has_kwrest as get_iseq_flags_has_kwrest; -pub use rb_get_iseq_flags_has_block as get_iseq_flags_has_block; -pub use rb_get_iseq_flags_ambiguous_param0 as get_iseq_flags_ambiguous_param0; -pub use rb_get_iseq_flags_accepts_no_kwarg as get_iseq_flags_accepts_no_kwarg; pub use rb_get_iseq_body_local_table_size as get_iseq_body_local_table_size; -pub use rb_get_iseq_body_param_keyword as get_iseq_body_param_keyword; -pub use rb_get_iseq_body_param_size as get_iseq_body_param_size; -pub use rb_get_iseq_body_param_lead_num as get_iseq_body_param_lead_num; -pub use rb_get_iseq_body_param_opt_num as get_iseq_body_param_opt_num; -pub use rb_get_iseq_body_param_opt_table as get_iseq_body_param_opt_table; pub use rb_get_cikw_keyword_len as get_cikw_keyword_len; pub use rb_get_cikw_keywords_idx as get_cikw_keywords_idx; pub use rb_get_call_data_ci as get_call_data_ci; @@ -306,11 +292,10 @@ pub fn iseq_escapes_ep(iseq: IseqPtr) -> bool { } /// Index of the local variable that has a rest parameter if any -pub fn iseq_rest_param_idx(iseq: IseqPtr) -> Option<i32> { - if !iseq.is_null() && unsafe { get_iseq_flags_has_rest(iseq) } { - let opt_num = unsafe { get_iseq_body_param_opt_num(iseq) }; - let lead_num = unsafe { get_iseq_body_param_lead_num(iseq) }; - Some(opt_num + lead_num) +pub fn iseq_rest_param_idx(params: &IseqParameters) -> Option<i32> { + // TODO(alan): replace with `params.rest_start` + if params.flags.has_rest() != 0 { + Some(params.opt_num + params.lead_num) } else { None } @@ -686,6 +671,20 @@ impl VALUE { } } +pub type IseqParameters = rb_iseq_constant_body_rb_iseq_parameters; + +/// Extension trait to enable method calls on [`IseqPtr`] +pub trait IseqAccess { + unsafe fn params<'a>(self) -> &'a IseqParameters; +} + +impl IseqAccess for IseqPtr { + /// Get a description of the ISEQ's signature. Analogous to `ISEQ_BODY(iseq)->param` in C. + unsafe fn params<'a>(self) -> &'a IseqParameters { + unsafe { &(*(*self).body).param } + } +} + impl From<IseqPtr> for VALUE { /// For `.into()` convenience fn from(iseq: IseqPtr) -> Self { diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 172b177c45..961fe1c142 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -1497,14 +1497,15 @@ fn can_direct_send(function: &mut Function, block: BlockId, iseq: *const rb_iseq can_send = false; function.push_insn(block, Insn::IncrCounter(counter)); }; + let params = unsafe { iseq.params() }; use Counter::*; - if unsafe { rb_get_iseq_flags_has_rest(iseq) } { count_failure(complex_arg_pass_param_rest) } - if unsafe { rb_get_iseq_flags_has_post(iseq) } { count_failure(complex_arg_pass_param_post) } - if unsafe { rb_get_iseq_flags_has_kw(iseq) } { count_failure(complex_arg_pass_param_kw) } - if unsafe { rb_get_iseq_flags_has_kwrest(iseq) } { count_failure(complex_arg_pass_param_kwrest) } - if unsafe { rb_get_iseq_flags_has_block(iseq) } { count_failure(complex_arg_pass_param_block) } - if unsafe { rb_get_iseq_flags_forwardable(iseq) } { count_failure(complex_arg_pass_param_forwardable) } + if 0 != params.flags.has_rest() { count_failure(complex_arg_pass_param_rest) } + if 0 != params.flags.has_post() { count_failure(complex_arg_pass_param_post) } + if 0 != params.flags.has_kw() { count_failure(complex_arg_pass_param_kw) } + if 0 != params.flags.has_kwrest() { count_failure(complex_arg_pass_param_kwrest) } + if 0 != params.flags.has_block() { count_failure(complex_arg_pass_param_block) } + if 0 != params.flags.forwardable() { count_failure(complex_arg_pass_param_forwardable) } if !can_send { function.set_dynamic_send_reason(send_insn, ComplexArgPass); @@ -1512,8 +1513,8 @@ fn can_direct_send(function: &mut Function, block: BlockId, iseq: *const rb_iseq } // Because we exclude e.g. post parameters above, they are also excluded from the sum below. - let lead_num = unsafe { get_iseq_body_param_lead_num(iseq) }; - let opt_num = unsafe { get_iseq_body_param_opt_num(iseq) }; + let lead_num = params.lead_num; + let opt_num = params.opt_num; can_send = c_int::try_from(args.len()) .as_ref() .map(|argc| (lead_num..=lead_num + opt_num).contains(argc)) @@ -2086,8 +2087,9 @@ impl Function { /// Set self.param_types. They are copied to the param types of jit_entry_blocks. fn set_param_types(&mut self) { let iseq = self.iseq; - let param_size = unsafe { get_iseq_body_param_size(iseq) }.to_usize(); - let rest_param_idx = iseq_rest_param_idx(iseq); + let params = unsafe { iseq.params() }; + let param_size = params.size.to_usize(); + let rest_param_idx = iseq_rest_param_idx(params); self.param_types.push(types::BasicObject); // self for local_idx in 0..param_size { @@ -4596,11 +4598,12 @@ fn insn_idx_at_offset(idx: u32, offset: i64) -> u32 { /// List of insn_idx that starts a JIT entry block pub fn jit_entry_insns(iseq: IseqPtr) -> Vec<u32> { // TODO(alan): Make an iterator type for this instead of copying all of the opt_table each call - let opt_num = unsafe { get_iseq_body_param_opt_num(iseq) }; + let params = unsafe { iseq.params() }; + let opt_num = params.opt_num; if opt_num > 0 { let mut result = vec![]; - let opt_table = unsafe { get_iseq_body_param_opt_table(iseq) }; // `opt_num + 1` entries + let opt_table = params.opt_table; // `opt_num + 1` entries for opt_idx in 0..=opt_num as isize { let insn_idx = unsafe { opt_table.offset(opt_idx).read().as_u32() }; result.push(insn_idx); @@ -5715,8 +5718,9 @@ fn compile_entry_state(fun: &mut Function) -> (InsnId, FrameState) { fun.push_insn(entry_block, Insn::EntryPoint { jit_entry_idx: None }); let iseq = fun.iseq; - let param_size = unsafe { get_iseq_body_param_size(iseq) }.to_usize(); - let rest_param_idx = iseq_rest_param_idx(iseq); + let params = unsafe { iseq.params() }; + let param_size = params.size.to_usize(); + let rest_param_idx = iseq_rest_param_idx(params); let self_param = fun.push_insn(entry_block, Insn::LoadSelf); let mut entry_state = FrameState::new(iseq); @@ -5748,9 +5752,10 @@ fn compile_jit_entry_block(fun: &mut Function, jit_entry_idx: usize, target_bloc /// Compile params and initial locals for a jit_entry_block fn compile_jit_entry_state(fun: &mut Function, jit_entry_block: BlockId, jit_entry_idx: usize) -> (InsnId, FrameState) { let iseq = fun.iseq; - let param_size = unsafe { get_iseq_body_param_size(iseq) }.to_usize(); - let opt_num: usize = unsafe { get_iseq_body_param_opt_num(iseq) }.try_into().expect("iseq param opt_num >= 0"); - let lead_num: usize = unsafe { get_iseq_body_param_lead_num(iseq) }.try_into().expect("iseq param lead_num >= 0"); + let params = unsafe { iseq.params() }; + let param_size = params.size.to_usize(); + let opt_num: usize = params.opt_num.try_into().expect("iseq param opt_num >= 0"); + let lead_num: usize = params.lead_num.try_into().expect("iseq param lead_num >= 0"); let passed_opt_num = jit_entry_idx; let self_param = fun.push_insn(jit_entry_block, Insn::Param); |
