mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
ZJIT: Get rid of CallInfo
This commit is contained in:
parent
096d48d7db
commit
0f7ee8e7a4
3 changed files with 69 additions and 84 deletions
|
@ -10,7 +10,7 @@ use crate::state::ZJITState;
|
|||
use crate::stats::{counter_ptr, Counter};
|
||||
use crate::{asm::CodeBlock, cruby::*, options::debug, virtualmem::CodePtr};
|
||||
use crate::backend::lir::{self, asm_comment, asm_ccall, Assembler, Opnd, SideExitContext, Target, CFP, C_ARG_OPNDS, C_RET_OPND, EC, NATIVE_STACK_PTR, NATIVE_BASE_PTR, SP};
|
||||
use crate::hir::{iseq_to_hir, Block, BlockId, BranchEdge, CallInfo, Invariant, RangeType, SideExitReason, SideExitReason::*, SpecialObjectType, SELF_PARAM_IDX};
|
||||
use crate::hir::{iseq_to_hir, Block, BlockId, BranchEdge, Invariant, RangeType, SideExitReason, SideExitReason::*, SpecialObjectType, SELF_PARAM_IDX};
|
||||
use crate::hir::{Const, FrameState, Function, Insn, InsnId};
|
||||
use crate::hir_type::{types, Type};
|
||||
use crate::options::get_option;
|
||||
|
@ -331,10 +331,10 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
|
|||
Insn::Jump(branch) => return gen_jump(jit, asm, branch),
|
||||
Insn::IfTrue { val, target } => return gen_if_true(jit, asm, opnd!(val), target),
|
||||
Insn::IfFalse { val, target } => return gen_if_false(jit, asm, opnd!(val), target),
|
||||
Insn::SendWithoutBlock { call_info, cd, state, self_val, args, .. } => gen_send_without_block(jit, asm, call_info, *cd, &function.frame_state(*state), opnd!(self_val), opnds!(args))?,
|
||||
Insn::SendWithoutBlock { cd, state, self_val, args, .. } => gen_send_without_block(jit, asm, *cd, &function.frame_state(*state), opnd!(self_val), opnds!(args))?,
|
||||
// Give up SendWithoutBlockDirect for 6+ args since asm.ccall() doesn't support it.
|
||||
Insn::SendWithoutBlockDirect { call_info, cd, state, self_val, args, .. } if args.len() + 1 > C_ARG_OPNDS.len() => // +1 for self
|
||||
gen_send_without_block(jit, asm, call_info, *cd, &function.frame_state(*state), opnd!(self_val), opnds!(args))?,
|
||||
Insn::SendWithoutBlockDirect { cd, state, self_val, args, .. } if args.len() + 1 > C_ARG_OPNDS.len() => // +1 for self
|
||||
gen_send_without_block(jit, asm, *cd, &function.frame_state(*state), opnd!(self_val), opnds!(args))?,
|
||||
Insn::SendWithoutBlockDirect { cme, iseq, self_val, args, state, .. } => gen_send_without_block_direct(cb, jit, asm, *cme, *iseq, opnd!(self_val), opnds!(args), &function.frame_state(*state))?,
|
||||
Insn::InvokeBuiltin { bf, args, state } => gen_invokebuiltin(asm, &function.frame_state(*state), bf, opnds!(args))?,
|
||||
Insn::Return { val } => return Some(gen_return(asm, opnd!(val))?),
|
||||
|
@ -763,7 +763,6 @@ fn gen_if_false(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, branch:
|
|||
fn gen_send_without_block(
|
||||
jit: &mut JITState,
|
||||
asm: &mut Assembler,
|
||||
call_info: &CallInfo,
|
||||
cd: *const rb_call_data,
|
||||
state: &FrameState,
|
||||
self_val: Opnd,
|
||||
|
@ -789,7 +788,7 @@ fn gen_send_without_block(
|
|||
gen_save_pc(asm, state);
|
||||
gen_save_sp(asm, 1 + args.len()); // +1 for receiver
|
||||
|
||||
asm_comment!(asm, "call #{} with dynamic dispatch", call_info.method_name);
|
||||
asm_comment!(asm, "call #{} with dynamic dispatch", ruby_call_method_name(cd));
|
||||
unsafe extern "C" {
|
||||
fn rb_vm_opt_send_without_block(ec: EcPtr, cfp: CfpPtr, cd: VALUE) -> VALUE;
|
||||
}
|
||||
|
|
|
@ -750,6 +750,16 @@ pub fn ruby_sym_to_rust_string(v: VALUE) -> String {
|
|||
ruby_str_to_rust_string(ruby_str)
|
||||
}
|
||||
|
||||
pub fn ruby_call_method_id(cd: *const rb_call_data) -> ID {
|
||||
let call_info = unsafe { rb_get_call_data_ci(cd) };
|
||||
unsafe { rb_vm_ci_mid(call_info) }
|
||||
}
|
||||
|
||||
pub fn ruby_call_method_name(cd: *const rb_call_data) -> String {
|
||||
let mid = ruby_call_method_id(cd);
|
||||
mid.contents_lossy().to_string()
|
||||
}
|
||||
|
||||
/// A location in Rust code for integrating with debugging facilities defined in C.
|
||||
/// Use the [src_loc!] macro to crate an instance.
|
||||
pub struct SourceLocation {
|
||||
|
@ -1211,6 +1221,21 @@ pub(crate) mod ids {
|
|||
name: to_s
|
||||
name: compile
|
||||
name: eval
|
||||
name: plus content: b"+"
|
||||
name: minus content: b"-"
|
||||
name: mult content: b"*"
|
||||
name: div content: b"/"
|
||||
name: modulo content: b"%"
|
||||
name: neq content: b"!="
|
||||
name: lt content: b"<"
|
||||
name: le content: b"<="
|
||||
name: gt content: b">"
|
||||
name: ge content: b">="
|
||||
name: and content: b"&"
|
||||
name: or content: b"|"
|
||||
name: freeze
|
||||
name: minusat content: b"-@"
|
||||
name: aref content: b"[]"
|
||||
}
|
||||
|
||||
/// Get an CRuby `ID` to an interned string, e.g. a particular method name.
|
||||
|
|
117
zjit/src/hir.rs
117
zjit/src/hir.rs
|
@ -107,11 +107,6 @@ impl std::fmt::Display for BranchEdge {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct CallInfo {
|
||||
pub method_name: String,
|
||||
}
|
||||
|
||||
/// Invalidation reasons
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Invariant {
|
||||
|
@ -515,11 +510,10 @@ pub enum Insn {
|
|||
|
||||
/// Send without block with dynamic dispatch
|
||||
/// Ignoring keyword arguments etc for now
|
||||
SendWithoutBlock { self_val: InsnId, call_info: CallInfo, cd: *const rb_call_data, args: Vec<InsnId>, state: InsnId },
|
||||
Send { self_val: InsnId, call_info: CallInfo, cd: *const rb_call_data, blockiseq: IseqPtr, args: Vec<InsnId>, state: InsnId },
|
||||
SendWithoutBlock { self_val: InsnId, cd: *const rb_call_data, args: Vec<InsnId>, state: InsnId },
|
||||
Send { self_val: InsnId, cd: *const rb_call_data, blockiseq: IseqPtr, args: Vec<InsnId>, state: InsnId },
|
||||
SendWithoutBlockDirect {
|
||||
self_val: InsnId,
|
||||
call_info: CallInfo,
|
||||
cd: *const rb_call_data,
|
||||
cme: *const rb_callable_method_entry_t,
|
||||
iseq: IseqPtr,
|
||||
|
@ -551,7 +545,7 @@ pub enum Insn {
|
|||
FixnumOr { left: InsnId, right: InsnId },
|
||||
|
||||
// Distinct from `SendWithoutBlock` with `mid:to_s` because does not have a patch point for String to_s being redefined
|
||||
ObjToString { val: InsnId, call_info: CallInfo, cd: *const rb_call_data, state: InsnId },
|
||||
ObjToString { val: InsnId, cd: *const rb_call_data, state: InsnId },
|
||||
AnyToString { val: InsnId, str: InsnId, state: InsnId },
|
||||
|
||||
/// Side-exit if val doesn't have the expected type.
|
||||
|
@ -680,25 +674,25 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> {
|
|||
Insn::Jump(target) => { write!(f, "Jump {target}") }
|
||||
Insn::IfTrue { val, target } => { write!(f, "IfTrue {val}, {target}") }
|
||||
Insn::IfFalse { val, target } => { write!(f, "IfFalse {val}, {target}") }
|
||||
Insn::SendWithoutBlock { self_val, call_info, args, .. } => {
|
||||
write!(f, "SendWithoutBlock {self_val}, :{}", call_info.method_name)?;
|
||||
Insn::SendWithoutBlock { self_val, cd, args, .. } => {
|
||||
write!(f, "SendWithoutBlock {self_val}, :{}", ruby_call_method_name(*cd))?;
|
||||
for arg in args {
|
||||
write!(f, ", {arg}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Insn::SendWithoutBlockDirect { self_val, call_info, iseq, args, .. } => {
|
||||
write!(f, "SendWithoutBlockDirect {self_val}, :{} ({:?})", call_info.method_name, self.ptr_map.map_ptr(iseq))?;
|
||||
Insn::SendWithoutBlockDirect { self_val, cd, iseq, args, .. } => {
|
||||
write!(f, "SendWithoutBlockDirect {self_val}, :{} ({:?})", ruby_call_method_name(*cd), self.ptr_map.map_ptr(iseq))?;
|
||||
for arg in args {
|
||||
write!(f, ", {arg}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Insn::Send { self_val, call_info, args, blockiseq, .. } => {
|
||||
Insn::Send { self_val, cd, args, blockiseq, .. } => {
|
||||
// For tests, we want to check HIR snippets textually. Addresses change
|
||||
// between runs, making tests fail. Instead, pick an arbitrary hex value to
|
||||
// use as a "pointer" so we can check the rest of the HIR.
|
||||
write!(f, "Send {self_val}, {:p}, :{}", self.ptr_map.map_ptr(blockiseq), call_info.method_name)?;
|
||||
write!(f, "Send {self_val}, {:p}, :{}", self.ptr_map.map_ptr(blockiseq), ruby_call_method_name(*cd))?;
|
||||
for arg in args {
|
||||
write!(f, ", {arg}")?;
|
||||
}
|
||||
|
@ -1134,9 +1128,8 @@ impl Function {
|
|||
&FixnumLe { left, right } => FixnumLe { left: find!(left), right: find!(right) },
|
||||
&FixnumAnd { left, right } => FixnumAnd { left: find!(left), right: find!(right) },
|
||||
&FixnumOr { left, right } => FixnumOr { left: find!(left), right: find!(right) },
|
||||
&ObjToString { val, ref call_info, cd, state } => ObjToString {
|
||||
&ObjToString { val, cd, state } => ObjToString {
|
||||
val: find!(val),
|
||||
call_info: call_info.clone(),
|
||||
cd: cd,
|
||||
state,
|
||||
},
|
||||
|
@ -1145,25 +1138,22 @@ impl Function {
|
|||
str: find!(str),
|
||||
state,
|
||||
},
|
||||
&SendWithoutBlock { self_val, ref call_info, cd, ref args, state } => SendWithoutBlock {
|
||||
&SendWithoutBlock { self_val, cd, ref args, state } => SendWithoutBlock {
|
||||
self_val: find!(self_val),
|
||||
call_info: call_info.clone(),
|
||||
cd: cd,
|
||||
args: find_vec!(args),
|
||||
state,
|
||||
},
|
||||
&SendWithoutBlockDirect { self_val, ref call_info, cd, cme, iseq, ref args, state } => SendWithoutBlockDirect {
|
||||
&SendWithoutBlockDirect { self_val, cd, cme, iseq, ref args, state } => SendWithoutBlockDirect {
|
||||
self_val: find!(self_val),
|
||||
call_info: call_info.clone(),
|
||||
cd: cd,
|
||||
cme: cme,
|
||||
iseq: iseq,
|
||||
args: find_vec!(args),
|
||||
state,
|
||||
},
|
||||
&Send { self_val, ref call_info, cd, blockiseq, ref args, state } => Send {
|
||||
&Send { self_val, cd, blockiseq, ref args, state } => Send {
|
||||
self_val: find!(self_val),
|
||||
call_info: call_info.clone(),
|
||||
cd: cd,
|
||||
blockiseq: blockiseq,
|
||||
args: find_vec!(args),
|
||||
|
@ -1477,39 +1467,39 @@ impl Function {
|
|||
assert!(self.blocks[block.0].insns.is_empty());
|
||||
for insn_id in old_insns {
|
||||
match self.find(insn_id) {
|
||||
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == "+" && args.len() == 1 =>
|
||||
Insn::SendWithoutBlock { self_val, args, state, cd, .. } if ruby_call_method_id(cd) == ID!(plus) && args.len() == 1 =>
|
||||
self.try_rewrite_fixnum_op(block, insn_id, &|left, right| Insn::FixnumAdd { left, right, state }, BOP_PLUS, self_val, args[0], state),
|
||||
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == "-" && args.len() == 1 =>
|
||||
Insn::SendWithoutBlock { self_val, args, state, cd, .. } if ruby_call_method_id(cd) == ID!(minus) && args.len() == 1 =>
|
||||
self.try_rewrite_fixnum_op(block, insn_id, &|left, right| Insn::FixnumSub { left, right, state }, BOP_MINUS, self_val, args[0], state),
|
||||
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == "*" && args.len() == 1 =>
|
||||
Insn::SendWithoutBlock { self_val, args, state, cd, .. } if ruby_call_method_id(cd) == ID!(mult) && args.len() == 1 =>
|
||||
self.try_rewrite_fixnum_op(block, insn_id, &|left, right| Insn::FixnumMult { left, right, state }, BOP_MULT, self_val, args[0], state),
|
||||
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == "/" && args.len() == 1 =>
|
||||
Insn::SendWithoutBlock { self_val, args, state, cd, .. } if ruby_call_method_id(cd) == ID!(div) && args.len() == 1 =>
|
||||
self.try_rewrite_fixnum_op(block, insn_id, &|left, right| Insn::FixnumDiv { left, right, state }, BOP_DIV, self_val, args[0], state),
|
||||
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == "%" && args.len() == 1 =>
|
||||
Insn::SendWithoutBlock { self_val, args, state, cd, .. } if ruby_call_method_id(cd) == ID!(modulo) && args.len() == 1 =>
|
||||
self.try_rewrite_fixnum_op(block, insn_id, &|left, right| Insn::FixnumMod { left, right, state }, BOP_MOD, self_val, args[0], state),
|
||||
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == "==" && args.len() == 1 =>
|
||||
Insn::SendWithoutBlock { self_val, args, state, cd, .. } if ruby_call_method_id(cd) == ID!(eq) && args.len() == 1 =>
|
||||
self.try_rewrite_fixnum_op(block, insn_id, &|left, right| Insn::FixnumEq { left, right }, BOP_EQ, self_val, args[0], state),
|
||||
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == "!=" && args.len() == 1 =>
|
||||
Insn::SendWithoutBlock { self_val, args, state, cd, .. } if ruby_call_method_id(cd) == ID!(neq) && args.len() == 1 =>
|
||||
self.try_rewrite_fixnum_op(block, insn_id, &|left, right| Insn::FixnumNeq { left, right }, BOP_NEQ, self_val, args[0], state),
|
||||
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == "<" && args.len() == 1 =>
|
||||
Insn::SendWithoutBlock { self_val, args, state, cd, .. } if ruby_call_method_id(cd) == ID!(lt) && args.len() == 1 =>
|
||||
self.try_rewrite_fixnum_op(block, insn_id, &|left, right| Insn::FixnumLt { left, right }, BOP_LT, self_val, args[0], state),
|
||||
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == "<=" && args.len() == 1 =>
|
||||
Insn::SendWithoutBlock { self_val, args, state, cd, .. } if ruby_call_method_id(cd) == ID!(le) && args.len() == 1 =>
|
||||
self.try_rewrite_fixnum_op(block, insn_id, &|left, right| Insn::FixnumLe { left, right }, BOP_LE, self_val, args[0], state),
|
||||
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == ">" && args.len() == 1 =>
|
||||
Insn::SendWithoutBlock { self_val, args, state, cd, .. } if ruby_call_method_id(cd) == ID!(gt) && args.len() == 1 =>
|
||||
self.try_rewrite_fixnum_op(block, insn_id, &|left, right| Insn::FixnumGt { left, right }, BOP_GT, self_val, args[0], state),
|
||||
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == ">=" && args.len() == 1 =>
|
||||
Insn::SendWithoutBlock { self_val, args, state, cd, .. } if ruby_call_method_id(cd) == ID!(ge) && args.len() == 1 =>
|
||||
self.try_rewrite_fixnum_op(block, insn_id, &|left, right| Insn::FixnumGe { left, right }, BOP_GE, self_val, args[0], state),
|
||||
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == "&" && args.len() == 1 =>
|
||||
Insn::SendWithoutBlock { self_val, args, state, cd, .. } if ruby_call_method_id(cd) == ID!(and) && args.len() == 1 =>
|
||||
self.try_rewrite_fixnum_op(block, insn_id, &|left, right| Insn::FixnumAnd { left, right }, BOP_AND, self_val, args[0], state),
|
||||
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == "|" && args.len() == 1 =>
|
||||
Insn::SendWithoutBlock { self_val, args, state, cd, .. } if ruby_call_method_id(cd) == ID!(or) && args.len() == 1 =>
|
||||
self.try_rewrite_fixnum_op(block, insn_id, &|left, right| Insn::FixnumOr { left, right }, BOP_OR, self_val, args[0], state),
|
||||
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == "freeze" && args.len() == 0 =>
|
||||
Insn::SendWithoutBlock { self_val, args, state, cd, .. } if ruby_call_method_id(cd) == ID!(freeze) && args.len() == 0 =>
|
||||
self.try_rewrite_freeze(block, insn_id, self_val, state),
|
||||
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == "-@" && args.len() == 0 =>
|
||||
Insn::SendWithoutBlock { self_val, args, state, cd, .. } if ruby_call_method_id(cd) == ID!(minusat) && args.len() == 0 =>
|
||||
self.try_rewrite_uminus(block, insn_id, self_val, state),
|
||||
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == "[]" && args.len() == 1 =>
|
||||
Insn::SendWithoutBlock { self_val, args, state, cd, .. } if ruby_call_method_id(cd) == ID!(aref) && args.len() == 1 =>
|
||||
self.try_rewrite_aref(block, insn_id, self_val, args[0], state),
|
||||
Insn::SendWithoutBlock { mut self_val, call_info, cd, args, state } => {
|
||||
Insn::SendWithoutBlock { mut self_val, cd, args, state } => {
|
||||
let frame_state = self.frame_state(state);
|
||||
let (klass, guard_equal_to) = if let Some(klass) = self.type_of(self_val).runtime_exact_ruby_class() {
|
||||
// If we know the class statically, use it to fold the lookup at compile-time.
|
||||
|
@ -1546,7 +1536,7 @@ impl Function {
|
|||
if let Some(expected) = guard_equal_to {
|
||||
self_val = self.push_insn(block, Insn::GuardBitEquals { val: self_val, expected, state });
|
||||
}
|
||||
let send_direct = self.push_insn(block, Insn::SendWithoutBlockDirect { self_val, call_info, cd, cme, iseq, args, state });
|
||||
let send_direct = self.push_insn(block, Insn::SendWithoutBlockDirect { self_val, cd, cme, iseq, args, state });
|
||||
self.make_equal_to(insn_id, send_direct);
|
||||
}
|
||||
Insn::GetConstantPath { ic, state, .. } => {
|
||||
|
@ -1569,12 +1559,12 @@ impl Function {
|
|||
self.insn_types[replacement.0] = self.infer_type(replacement);
|
||||
self.make_equal_to(insn_id, replacement);
|
||||
}
|
||||
Insn::ObjToString { val, call_info, cd, state, .. } => {
|
||||
Insn::ObjToString { val, cd, state, .. } => {
|
||||
if self.is_a(val, types::String) {
|
||||
// behaves differently from `SendWithoutBlock` with `mid:to_s` because ObjToString should not have a patch point for String to_s being redefined
|
||||
self.make_equal_to(insn_id, val);
|
||||
} else {
|
||||
let replacement = self.push_insn(block, Insn::SendWithoutBlock { self_val: val, call_info, cd, args: vec![], state });
|
||||
let replacement = self.push_insn(block, Insn::SendWithoutBlock { self_val: val, cd, args: vec![], state });
|
||||
self.make_equal_to(insn_id, replacement)
|
||||
}
|
||||
}
|
||||
|
@ -2934,18 +2924,13 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
|
|||
}
|
||||
let argc = unsafe { vm_ci_argc((*cd).ci) };
|
||||
|
||||
let method_name = unsafe {
|
||||
let mid = rb_vm_ci_mid(call_info);
|
||||
mid.contents_lossy().into_owned()
|
||||
};
|
||||
|
||||
assert_eq!(1, argc, "opt_aref_with should only be emitted for argc=1");
|
||||
let aref_arg = fun.push_insn(block, Insn::Const { val: Const::Value(get_arg(pc, 0)) });
|
||||
let args = vec![aref_arg];
|
||||
|
||||
let recv = state.stack_pop()?;
|
||||
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
|
||||
let send = fun.push_insn(block, Insn::SendWithoutBlock { self_val: recv, call_info: CallInfo { method_name }, cd, args, state: exit_id });
|
||||
let send = fun.push_insn(block, Insn::SendWithoutBlock { self_val: recv, cd, args, state: exit_id });
|
||||
state.stack_push(send);
|
||||
}
|
||||
YARVINSN_opt_neq => {
|
||||
|
@ -2960,11 +2945,6 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
|
|||
}
|
||||
let argc = unsafe { vm_ci_argc((*cd).ci) };
|
||||
|
||||
|
||||
let method_name = unsafe {
|
||||
let mid = rb_vm_ci_mid(call_info);
|
||||
mid.contents_lossy().into_owned()
|
||||
};
|
||||
let mut args = vec![];
|
||||
for _ in 0..argc {
|
||||
args.push(state.stack_pop()?);
|
||||
|
@ -2973,7 +2953,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
|
|||
|
||||
let recv = state.stack_pop()?;
|
||||
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
|
||||
let send = fun.push_insn(block, Insn::SendWithoutBlock { self_val: recv, call_info: CallInfo { method_name }, cd, args, state: exit_id });
|
||||
let send = fun.push_insn(block, Insn::SendWithoutBlock { self_val: recv, cd, args, state: exit_id });
|
||||
state.stack_push(send);
|
||||
}
|
||||
YARVINSN_opt_hash_freeze |
|
||||
|
@ -2994,14 +2974,9 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
|
|||
assert_eq!(0, argc, "{name} should not have args");
|
||||
let args = vec![];
|
||||
|
||||
let method_name = unsafe {
|
||||
let mid = rb_vm_ci_mid(call_info);
|
||||
mid.contents_lossy().into_owned()
|
||||
};
|
||||
|
||||
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
|
||||
let recv = fun.push_insn(block, Insn::Const { val: Const::Value(get_arg(pc, 0)) });
|
||||
let send = fun.push_insn(block, Insn::SendWithoutBlock { self_val: recv, call_info: CallInfo { method_name }, cd, args, state: exit_id });
|
||||
let send = fun.push_insn(block, Insn::SendWithoutBlock { self_val: recv, cd, args, state: exit_id });
|
||||
state.stack_push(send);
|
||||
}
|
||||
|
||||
|
@ -3051,11 +3026,6 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
|
|||
}
|
||||
let argc = unsafe { vm_ci_argc((*cd).ci) };
|
||||
|
||||
|
||||
let method_name = unsafe {
|
||||
let mid = rb_vm_ci_mid(call_info);
|
||||
mid.contents_lossy().into_owned()
|
||||
};
|
||||
let mut args = vec![];
|
||||
for _ in 0..argc {
|
||||
args.push(state.stack_pop()?);
|
||||
|
@ -3064,7 +3034,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
|
|||
|
||||
let recv = state.stack_pop()?;
|
||||
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
|
||||
let send = fun.push_insn(block, Insn::SendWithoutBlock { self_val: recv, call_info: CallInfo { method_name }, cd, args, state: exit_id });
|
||||
let send = fun.push_insn(block, Insn::SendWithoutBlock { self_val: recv, cd, args, state: exit_id });
|
||||
state.stack_push(send);
|
||||
}
|
||||
YARVINSN_send => {
|
||||
|
@ -3079,10 +3049,6 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
|
|||
}
|
||||
let argc = unsafe { vm_ci_argc((*cd).ci) };
|
||||
|
||||
let method_name = unsafe {
|
||||
let mid = rb_vm_ci_mid(call_info);
|
||||
mid.contents_lossy().into_owned()
|
||||
};
|
||||
let mut args = vec![];
|
||||
for _ in 0..argc {
|
||||
args.push(state.stack_pop()?);
|
||||
|
@ -3091,7 +3057,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
|
|||
|
||||
let recv = state.stack_pop()?;
|
||||
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
|
||||
let send = fun.push_insn(block, Insn::Send { self_val: recv, call_info: CallInfo { method_name }, cd, blockiseq, args, state: exit_id });
|
||||
let send = fun.push_insn(block, Insn::Send { self_val: recv, cd, blockiseq, args, state: exit_id });
|
||||
state.stack_push(send);
|
||||
}
|
||||
YARVINSN_getglobal => {
|
||||
|
@ -3177,14 +3143,9 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
|
|||
let argc = unsafe { vm_ci_argc((*cd).ci) };
|
||||
assert_eq!(0, argc, "objtostring should not have args");
|
||||
|
||||
let method_name: String = unsafe {
|
||||
let mid = rb_vm_ci_mid(call_info);
|
||||
mid.contents_lossy().into_owned()
|
||||
};
|
||||
|
||||
let recv = state.stack_pop()?;
|
||||
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
|
||||
let objtostring = fun.push_insn(block, Insn::ObjToString { val: recv, call_info: CallInfo { method_name }, cd, state: exit_id });
|
||||
let objtostring = fun.push_insn(block, Insn::ObjToString { val: recv, cd, state: exit_id });
|
||||
state.stack_push(objtostring)
|
||||
}
|
||||
YARVINSN_anytostring => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue