summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zjit/src/codegen.rs9
-rw-r--r--zjit/src/cruby.rs37
-rw-r--r--zjit/src/hir.rs39
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);