diff --git a/yjit/src/asm/x86_64/mod.rs b/yjit/src/asm/x86_64/mod.rs index fdfac82f92..399c2e8c7e 100644 --- a/yjit/src/asm/x86_64/mod.rs +++ b/yjit/src/asm/x86_64/mod.rs @@ -245,7 +245,7 @@ pub const R13B: X86Opnd = X86Opnd::Reg(X86Reg { num_bits: 8, reg_type: RegType:: pub const R14B: X86Opnd = X86Opnd::Reg(X86Reg { num_bits: 8, reg_type: RegType::GP, reg_no: 14 }); pub const R15B: X86Opnd = X86Opnd::Reg(X86Reg { num_bits: 8, reg_type: RegType::GP, reg_no: 15 }); -// C argument registers +// C argument registers on this platform pub const C_ARG_REGS: [X86Opnd; 6] = [RDI, RSI, RDX, RCX, R8, R9]; //=========================================================================== diff --git a/yjit/src/backend/ir.rs b/yjit/src/backend/ir.rs index 63bf85f3a0..a077eb1945 100644 --- a/yjit/src/backend/ir.rs +++ b/yjit/src/backend/ir.rs @@ -6,7 +6,7 @@ use std::fmt; use std::convert::From; use crate::cruby::{VALUE}; use crate::virtualmem::{CodePtr}; -use crate::asm::{CodeBlock}; +use crate::asm::{CodeBlock, uimm_num_bits, imm_num_bits}; use crate::asm::x86_64::{X86Opnd, X86Imm, X86UImm, X86Reg, X86Mem, RegType}; use crate::core::{Context, Type, TempMapping}; use crate::codegen::{JITState}; @@ -21,6 +21,9 @@ pub const EC: Opnd = _EC; pub const CFP: Opnd = _CFP; pub const SP: Opnd = _SP; +pub const C_ARG_OPNDS: [Opnd; 6] = _C_ARG_OPNDS; +pub const C_RET_OPND: Opnd = _C_RET_OPND; + /// Instruction opcodes #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum Op @@ -77,6 +80,9 @@ pub enum Op // Compare two operands Cmp, + // Unconditional jump which takes an address operand + JmpOpnd, + // Low-level conditional jump instructions Jbe, Je, @@ -92,110 +98,8 @@ pub enum Op // C function return CRet, - /* - // The following are conditional jump instructions. They all accept as their - // first operand an EIR_LABEL_NAME, which is used as the target of the jump. - // - // The OP_JUMP_EQ instruction accepts two additional operands, to be - // compared for equality. If they're equal, then the generated code jumps to - // the target label. If they're not, then it continues on to the next - // instruction. - JumpEq, - - // The OP_JUMP_NE instruction is very similar to the OP_JUMP_EQ instruction, - // except it compares for inequality instead. - JumpNe, - - // Checks the overflow flag and conditionally jumps to the target if it is - // currently set. - JumpOvf, - - // A low-level call instruction for calling a function by a pointer. It - // accepts one operand of type EIR_IMM that should be a pointer to the - // function. Usually this is done by first casting the function to a void*, - // as in: ir_const_ptr((void *)&my_function)). - Call, - - // Calls a function by a pointer and returns an operand that contains the - // result of the function. Accepts as its operands a pointer to a function - // of type EIR_IMM (usually generated from ir_const_ptr) and a variable - // number of arguments to the function being called. - // - // This is the higher-level instruction that should be used when you want to - // call a function with arguments, as opposed to OP_CALL which is - // lower-level and just calls a function without moving arguments into - // registers for you. - CCall, - - // Returns from the function being generated immediately. This is different - // from OP_RETVAL in that it does nothing with the return value register - // (whatever is in there is what will get returned). Accepts no operands. - Ret, - - // First, moves a value into the return value register. Then, returns from - // the generated function. Accepts as its only operand the value that should - // be returned from the generated function. - RetVal, - - // A conditional move instruction that should be preceeded at some point by - // an OP_CMP instruction that would have set the requisite comparison flags. - // Accepts 2 operands, both of which are expected to be of the EIR_REG type. - // - // If the comparison indicates the left compared value is greater than or - // equal to the right compared value, then the conditional move is executed, - // otherwise we just continue on to the next instruction. - // - // This is considered a low-level instruction, and the OP_SELECT_* variants - // should be preferred if possible. - CMovGE, - - // The same as OP_CMOV_GE, except the comparison is greater than. - CMovGT, - - // The same as OP_CMOV_GE, except the comparison is less than or equal. - CMovLE, - - // The same as OP_CMOV_GE, except the comparison is less than. - CMovLT, - - // Selects between two different values based on a comparison of two other - // values. Accepts 4 operands. The first two are the basis of the - // comparison. The second two are the "then" case and the "else" case. You - // can effectively think of this instruction as a ternary operation, where - // the first two values are being compared. - // - // OP_SELECT_GE performs the described ternary using a greater than or equal - // comparison, that is if the first operand is greater than or equal to the - // second operand. - SelectGE, - - // The same as OP_SELECT_GE, except the comparison is greater than. - SelectGT, - - // The same as OP_SELECT_GE, except the comparison is less than or equal. - SelectLE, - - // The same as OP_SELECT_GE, except the comparison is less than. - SelectLT, - - // For later: - // These encode Ruby true/false semantics - // Can be used to enable op fusion of Ruby compare + branch. - // OP_JUMP_TRUE, // (opnd, target) - // OP_JUMP_FALSE, // (opnd, target) - - // For later: - // OP_GUARD_HEAP, // (opnd, target) - // OP_GUARD_IMM, // (opnd, target) - // OP_GUARD_FIXNUM, // (opnd, target) - - // For later: - // OP_COUNTER_INC, (counter_name) - - // For later: - // OP_LEA, - // OP_TEST, - */ + // Trigger a debugger breakpoint + Breakpoint, } // Memory location @@ -256,6 +160,12 @@ impl Opnd } } +impl From for Opnd { + fn from(value: usize) -> Self { + Opnd::UImm(value.try_into().unwrap()) + } +} + impl From for Opnd { fn from(value: VALUE) -> Self { let VALUE(uimm) = value; @@ -522,6 +432,18 @@ impl Assembler let opnd1 = asm.load(opnds[1]); asm.push_insn(op, vec![opnds[0], opnd1], None); }, + + [Opnd::Mem(_), Opnd::UImm(val)] => { + if uimm_num_bits(*val) > 32 { + let opnd1 = asm.load(opnds[1]); + asm.push_insn(op, vec![opnds[0], opnd1], None); + } + else + { + asm.push_insn(op, opnds, target); + } + }, + _ => { asm.push_insn(op, opnds, target); } @@ -609,7 +531,7 @@ impl Assembler // C return values need to be mapped to the C return register if op == Op::CCall { - out_reg = Opnd::Reg(take_reg(&mut pool, ®s, &RET_REG)) + out_reg = Opnd::Reg(take_reg(&mut pool, ®s, &C_RET_REG)) } // If this instruction's first operand maps to a register and @@ -689,6 +611,18 @@ macro_rules! def_push_jcc { }; } +macro_rules! def_push_0_opnd_no_out { + ($op_name:ident, $opcode:expr) => { + impl Assembler + { + pub fn $op_name(&mut self) + { + self.push_insn($opcode, vec![], None); + } + } + }; +} + macro_rules! def_push_1_opnd { ($op_name:ident, $opcode:expr) => { impl Assembler @@ -737,6 +671,7 @@ macro_rules! def_push_2_opnd_no_out { }; } +def_push_1_opnd_no_out!(jmp_opnd, Op::JmpOpnd); def_push_jcc!(je, Op::Je); def_push_jcc!(jbe, Op::Jbe); def_push_jcc!(jnz, Op::Jnz); @@ -752,6 +687,7 @@ def_push_2_opnd_no_out!(store, Op::Store); def_push_2_opnd_no_out!(mov, Op::Mov); def_push_2_opnd_no_out!(cmp, Op::Cmp); def_push_2_opnd_no_out!(test, Op::Test); +def_push_0_opnd_no_out!(breakpoint, Op::Breakpoint); // NOTE: these methods are temporary and will likely move // to context.rs later diff --git a/yjit/src/backend/x86_64/mod.rs b/yjit/src/backend/x86_64/mod.rs index 467a347b01..748bf5aea0 100644 --- a/yjit/src/backend/x86_64/mod.rs +++ b/yjit/src/backend/x86_64/mod.rs @@ -6,7 +6,7 @@ use crate::asm::{CodeBlock}; use crate::asm::x86_64::*; use crate::codegen::{JITState}; use crate::cruby::*; -use crate::backend::ir::*; +use crate::backend::ir::{Assembler, Opnd, Target, Op, Mem}; // Use the x86 register type for this platform pub type Reg = X86Reg; @@ -16,8 +16,19 @@ pub const _CFP: Opnd = Opnd::Reg(R13_REG); pub const _EC: Opnd = Opnd::Reg(R12_REG); pub const _SP: Opnd = Opnd::Reg(RBX_REG); +// C argument registers on this platform +pub const _C_ARG_OPNDS: [Opnd; 6] = [ + Opnd::Reg(RDI_REG), + Opnd::Reg(RSI_REG), + Opnd::Reg(RDX_REG), + Opnd::Reg(RCX_REG), + Opnd::Reg(R8_REG), + Opnd::Reg(R9_REG) +]; + // C return value register on this platform -pub const RET_REG: Reg = RAX_REG; +pub const C_RET_REG: Reg = RAX_REG; +pub const _C_RET_OPND: Opnd = Opnd::Reg(RAX_REG); /// Map Opnd to X86Opnd impl From for X86Opnd { @@ -58,7 +69,7 @@ impl Assembler ] } - /// Emit platform-specific machine code + /// Split IR instructions for the x86 platform fn x86_split(mut self) -> Assembler { let live_ranges: Vec = std::mem::take(&mut self.live_ranges); @@ -76,7 +87,8 @@ impl Assembler } }, - [Opnd::Mem(_), _] => { + // We have to load memory and register operands to avoid corrupting them + [Opnd::Mem(_) | Opnd::Reg(_), _] => { let opnd0 = asm.load(opnds[0]); asm.push_insn(op, vec![opnd0, opnds[1]], None); return; @@ -154,7 +166,7 @@ impl Assembler Op::CRet => { // TODO: bias allocation towards return register - if insn.opnds[0] != Opnd::Reg(RET_REG) { + if insn.opnds[0] != Opnd::Reg(C_RET_REG) { mov(cb, RAX, insn.opnds[0].into()); } @@ -167,17 +179,11 @@ impl Assembler // Test and set flags Op::Test => test(cb, insn.opnds[0].into(), insn.opnds[1].into()), - Op::Je => { - match insn.target.unwrap() { - Target::Label(idx) => { + Op::JmpOpnd => jmp_rm(cb, insn.opnds[0].into()), - dbg!(idx); - je_label(cb, idx); + Op::Je => je_label(cb, insn.target.unwrap().unwrap_label_idx()), - }, - _ => unimplemented!() - } - } + Op::Breakpoint => int3(cb), _ => panic!("unsupported instruction passed to x86 backend: {:?}", insn.op) }; diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 01c0b7ee85..4d5e73686d 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -1,7 +1,7 @@ // We use the YARV bytecode constants which have a CRuby-style name #![allow(non_upper_case_globals)] -use crate::asm::x86_64::*; +//use crate::asm::x86_64::*; use crate::asm::*; use crate::backend::ir::*; use crate::core::*; @@ -25,15 +25,15 @@ use std::slice; pub use crate::virtualmem::CodePtr; // Callee-saved registers -pub const REG_CFP: X86Opnd = R13; -pub const REG_EC: X86Opnd = R12; -pub const REG_SP: X86Opnd = RBX; +//pub const REG_CFP: X86Opnd = R13; +//pub const REG_EC: X86Opnd = R12; +//pub const REG_SP: X86Opnd = RBX; // Scratch registers used by YJIT -pub const REG0: X86Opnd = RAX; -pub const REG0_32: X86Opnd = EAX; -pub const REG0_8: X86Opnd = AL; -pub const REG1: X86Opnd = RCX; +//pub const REG0: X86Opnd = RAX; +//pub const REG0_32: X86Opnd = EAX; +//pub const REG0_8: X86Opnd = AL; +//pub const REG1: X86Opnd = RCX; // A block that can be invalidated needs space to write a jump. // We'll reserve a minimum size for any block that could @@ -210,19 +210,25 @@ fn add_comment(cb: &mut CodeBlock, comment_str: &str) { /// Increment a profiling counter with counter_name #[cfg(not(feature = "stats"))] macro_rules! gen_counter_incr { - ($cb:tt, $counter_name:ident) => {}; + ($asm:tt, $counter_name:ident) => {}; } #[cfg(feature = "stats")] macro_rules! gen_counter_incr { - ($cb:tt, $counter_name:ident) => { + ($asm:tt, $counter_name:ident) => { if (get_option!(gen_stats)) { // Get a pointer to the counter variable let ptr = ptr_to_counter!($counter_name); - // Use REG1 because there might be return value in REG0 - mov($cb, REG1, const_ptr_opnd(ptr as *const u8)); - write_lock_prefix($cb); // for ractors. - add($cb, mem_opnd(64, REG1, 0), imm_opnd(1)); + // Load the pointer into a register + let ptr_reg = $asm.load(Opnd::const_ptr(ptr as *const u8)); + let counter_opnd = Opnd::mem(64, ptr_reg, 0); + + // FIXME: do we want an atomic add, or an atomic store or swap for arm? + //write_lock_prefix($cb); // for ractors. + + // Increment and store the updated value + let incr_opnd = $asm.add(counter_opnd, 1.into()); + $asm.store(counter_opnd, incr_opnd); } }; } @@ -292,8 +298,7 @@ fn gen_save_sp(jit: &JITState, asm: &mut Assembler, ctx: &mut Context) { fn jit_prepare_routine_call( jit: &mut JITState, ctx: &mut Context, - asm: &mut Assembler, - scratch_reg: X86Opnd, + asm: &mut Assembler ) { jit.record_boundary_patch_point = true; jit_save_pc(jit, asm); @@ -396,6 +401,9 @@ fn verify_ctx(jit: &JITState, ctx: &Context) { fn gen_exit(exit_pc: *mut VALUE, ctx: &Context, cb: &mut CodeBlock) -> CodePtr { let code_ptr = cb.get_write_ptr(); + todo!(); + + /* add_comment(cb, "exit to interpreter"); // Generate the code to exit to the interpreters @@ -432,6 +440,7 @@ fn gen_exit(exit_pc: *mut VALUE, ctx: &Context, cb: &mut CodeBlock) -> CodePtr { ret(cb); return code_ptr; + */ } // Fill code_for_exit_from_stub. This is used by branch_stub_hit() to exit @@ -442,16 +451,20 @@ fn gen_code_for_exit_from_stub(ocb: &mut OutlinedCb) -> CodePtr { let ocb = ocb.unwrap(); let code_ptr = ocb.get_write_ptr(); + todo!(); + + /* gen_counter_incr!(ocb, exit_from_branch_stub); - pop(ocb, REG_SP); - pop(ocb, REG_EC); - pop(ocb, REG_CFP); + cpop(ocb, REG_SP); + cpop(ocb, REG_EC); + cpop(ocb, REG_CFP); mov(ocb, RAX, uimm_opnd(Qundef.into())); ret(ocb); return code_ptr; + */ } // :side-exit: @@ -504,6 +517,9 @@ fn gen_full_cfunc_return(ocb: &mut OutlinedCb) -> CodePtr { let cb = ocb.unwrap(); let code_ptr = cb.get_write_ptr(); + todo!(); + + /* // This chunk of code expect REG_EC to be filled properly and // RAX to contain the return value of the C method. @@ -524,6 +540,7 @@ fn gen_full_cfunc_return(ocb: &mut OutlinedCb) -> CodePtr { ret(cb); return code_ptr; + */ } /// Generate a continuation for leave that exits to the interpreter at REG_CFP->pc. @@ -531,6 +548,7 @@ fn gen_full_cfunc_return(ocb: &mut OutlinedCb) -> CodePtr { fn gen_leave_exit(ocb: &mut OutlinedCb) -> CodePtr { let ocb = ocb.unwrap(); let code_ptr = ocb.get_write_ptr(); + let mut asm = Assembler::new(); // Note, gen_leave() fully reconstructs interpreter state and leaves the // return value in RAX before coming here. @@ -539,11 +557,22 @@ fn gen_leave_exit(ocb: &mut OutlinedCb) -> CodePtr { // Every exit to the interpreter should be counted //gen_counter_incr!(ocb, leave_interp_return); - pop(ocb, REG_SP); - pop(ocb, REG_EC); - pop(ocb, REG_CFP); + asm.cpop(SP); + asm.cpop(EC); + asm.cpop(CFP); - ret(ocb); + // FIXME: we're currently assuming that the return value is in RAX, + // left there by gen_leave() ... + // + // What are our options? + // We could put the return value in C_RET_REG? + // Then call asm.ret with C_RET_REG? + + + + asm.cret(C_RET_OPND); + + asm.compile(ocb); return code_ptr; } @@ -604,8 +633,8 @@ pub fn gen_entry_prologue(cb: &mut CodeBlock, iseq: IseqPtr, insn_idx: u32) -> O asm.cpush(SP); // We are passed EC and CFP as arguments - asm.mov(EC, C_ARG_REGS[0].into()); - asm.mov(CFP, C_ARG_REGS[1].into()); + asm.mov(EC, C_ARG_OPNDS[0]); + asm.mov(CFP, C_ARG_OPNDS[1]); // Load the current SP from the CFP into REG_SP asm.mov(SP, Opnd::mem(64, CFP, RUBY_OFFSET_CFP_SP)); @@ -765,7 +794,7 @@ pub fn gen_single_block( // :count-placement: // Count bytecode instructions that execute in generated code. // Note that the increment happens even when the output takes side exit. - gen_counter_incr!(cb, exec_instruction); + gen_counter_incr!(asm, exec_instruction); // Add a comment for the name of the YARV instruction asm.comment(&insn_name(opcode)); @@ -919,7 +948,7 @@ fn gen_swap( asm: &mut Assembler, _ocb: &mut OutlinedCb, ) -> CodegenStatus { - stack_swap(jit, ctx, asm, 0, 1, REG0, REG1); + stack_swap(jit, ctx, asm, 0, 1); KeepCompiling } @@ -929,8 +958,6 @@ fn stack_swap( asm: &mut Assembler, offset0: u16, offset1: u16, - _reg0: X86Opnd, - _reg1: X86Opnd, ) { let stack0_mem = ctx.ir_stack_opnd(offset0 as i32); let stack1_mem = ctx.ir_stack_opnd(offset1 as i32); @@ -947,56 +974,26 @@ fn stack_swap( ctx.set_opnd_mapping(StackOpnd(offset1), mapping0); } - - - - - - - - - -/* fn gen_putnil( jit: &mut JITState, ctx: &mut Context, - cb: &mut CodeBlock, + asm: &mut Assembler, _ocb: &mut OutlinedCb, ) -> CodegenStatus { - jit_putobject(jit, ctx, cb, Qnil); + jit_putobject(jit, ctx, asm, Qnil); KeepCompiling } -fn jit_putobject(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, arg: VALUE) { +fn jit_putobject(jit: &mut JITState, ctx: &mut Context, asm: &mut Assembler, arg: VALUE) { let val_type: Type = Type::from(arg); let stack_top = ctx.stack_push(val_type); - - if arg.special_const_p() { - // Immediates will not move and do not need to be tracked for GC - // Thanks to this we can mov directly to memory when possible. - let imm = imm_opnd(arg.as_i64()); - - // 64-bit immediates can't be directly written to memory - if imm.num_bits() <= 32 { - mov(cb, stack_top, imm); - } else { - mov(cb, REG0, imm); - mov(cb, stack_top, REG0); - } - } else { - // Load the value to push into REG0 - // Note that this value may get moved by the GC - jit_mov_gc_ptr(jit, cb, REG0, arg); - - // Write argument at SP - mov(cb, stack_top, REG0); - } + asm.mov(stack_top, arg.into()); } fn gen_putobject_int2fix( jit: &mut JITState, ctx: &mut Context, - cb: &mut CodeBlock, + asm: &mut Assembler, _ocb: &mut OutlinedCb, ) -> CodegenStatus { let opcode = jit.opcode; @@ -1006,22 +1003,23 @@ fn gen_putobject_int2fix( 1 }; - jit_putobject(jit, ctx, cb, VALUE::fixnum_from_usize(cst_val)); + jit_putobject(jit, ctx, asm, VALUE::fixnum_from_usize(cst_val)); KeepCompiling } fn gen_putobject( jit: &mut JITState, ctx: &mut Context, - cb: &mut CodeBlock, + asm: &mut Assembler, _ocb: &mut OutlinedCb, ) -> CodegenStatus { let arg: VALUE = jit_get_arg(jit, 0); - jit_putobject(jit, ctx, cb, arg); + jit_putobject(jit, ctx, asm, arg); KeepCompiling } +/* fn gen_putself( _jit: &mut JITState, ctx: &mut Context, @@ -5250,48 +5248,53 @@ fn gen_invokesuper( _ => unreachable!(), } } +*/ fn gen_leave( jit: &mut JITState, ctx: &mut Context, - cb: &mut CodeBlock, + asm: &mut Assembler, ocb: &mut OutlinedCb, ) -> CodegenStatus { // Only the return value should be on the stack assert!(ctx.get_stack_size() == 1); + // FIXME + /* // Create a side-exit to fall back to the interpreter - let side_exit = get_side_exit(jit, ocb, ctx); - - // Load environment pointer EP from CFP - mov(cb, REG1, mem_opnd(64, REG_CFP, RUBY_OFFSET_CFP_EP)); + //let side_exit = get_side_exit(jit, ocb, ctx); // Check for interrupts - add_comment(cb, "check for interrupts"); - gen_check_ints(cb, counted_exit!(ocb, side_exit, leave_se_interrupt)); - - // Load the return value - mov(cb, REG0, ctx.stack_pop(1)); + //gen_check_ints(cb, counted_exit!(ocb, side_exit, leave_se_interrupt)); + */ // Pop the current frame (ec->cfp++) // Note: the return PC is already in the previous CFP - add_comment(cb, "pop stack frame"); - add(cb, REG_CFP, uimm_opnd(RUBY_SIZEOF_CONTROL_FRAME as u64)); - mov(cb, mem_opnd(64, REG_EC, RUBY_OFFSET_EC_CFP), REG_CFP); + asm.comment("pop stack frame"); + let incr_cfp = asm.add(CFP, RUBY_SIZEOF_CONTROL_FRAME.into()); + asm.mov(CFP, incr_cfp); + asm.mov(Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP), incr_cfp); + + // Load the return value + let retval_opnd = ctx.stack_pop(1); + + // Move the return value into the C return register for gen_leave_exit() + asm.mov(C_RET_OPND, retval_opnd); // Reload REG_SP for the caller and write the return value. // Top of the stack is REG_SP[0] since the caller has sp_offset=1. - mov(cb, REG_SP, mem_opnd(64, REG_CFP, RUBY_OFFSET_CFP_SP)); - mov(cb, mem_opnd(64, REG_SP, 0), REG0); + asm.mov(SP, Opnd::mem(64, CFP, RUBY_OFFSET_CFP_SP)); + asm.mov(Opnd::mem(64, SP, 0), C_RET_OPND); // Jump to the JIT return address on the frame that was just popped let offset_to_jit_return = -(RUBY_SIZEOF_CONTROL_FRAME as i32) + (RUBY_OFFSET_CFP_JIT_RETURN as i32); - jmp_rm(cb, mem_opnd(64, REG_CFP, offset_to_jit_return)); + asm.jmp_opnd(Opnd::mem(64, CFP, offset_to_jit_return)); EndBlock } +/* fn gen_getglobal( jit: &mut JITState, ctx: &mut Context, @@ -5958,21 +5961,21 @@ fn get_gen_fn(opcode: VALUE) -> Option { match opcode { YARVINSN_nop => Some(gen_nop), - //YARVINSN_pop => Some(gen_pop), + YARVINSN_pop => Some(gen_pop), YARVINSN_dup => Some(gen_dup), YARVINSN_dupn => Some(gen_dupn), YARVINSN_swap => Some(gen_swap), - - /* YARVINSN_putnil => Some(gen_putnil), YARVINSN_putobject => Some(gen_putobject), YARVINSN_putobject_INT2FIX_0_ => Some(gen_putobject_int2fix), YARVINSN_putobject_INT2FIX_1_ => Some(gen_putobject_int2fix), - YARVINSN_putself => Some(gen_putself), - YARVINSN_putspecialobject => Some(gen_putspecialobject), - YARVINSN_setn => Some(gen_setn), - YARVINSN_topn => Some(gen_topn), - YARVINSN_adjuststack => Some(gen_adjuststack), + //YARVINSN_putself => Some(gen_putself), + //YARVINSN_putspecialobject => Some(gen_putspecialobject), + //YARVINSN_setn => Some(gen_setn), + //YARVINSN_topn => Some(gen_topn), + //YARVINSN_adjuststack => Some(gen_adjuststack), + + /* YARVINSN_getlocal => Some(gen_getlocal), YARVINSN_getlocal_WC_0 => Some(gen_getlocal_wc0), YARVINSN_getlocal_WC_1 => Some(gen_getlocal_wc1), @@ -6028,14 +6031,16 @@ fn get_gen_fn(opcode: VALUE) -> Option { YARVINSN_branchunless => Some(gen_branchunless), YARVINSN_branchnil => Some(gen_branchnil), YARVINSN_jump => Some(gen_jump), + */ - YARVINSN_getblockparamproxy => Some(gen_getblockparamproxy), - YARVINSN_getblockparam => Some(gen_getblockparam), - YARVINSN_opt_send_without_block => Some(gen_opt_send_without_block), - YARVINSN_send => Some(gen_send), - YARVINSN_invokesuper => Some(gen_invokesuper), + //YARVINSN_getblockparamproxy => Some(gen_getblockparamproxy), + //YARVINSN_getblockparam => Some(gen_getblockparam), + //YARVINSN_opt_send_without_block => Some(gen_opt_send_without_block), + //YARVINSN_send => Some(gen_send), + //YARVINSN_invokesuper => Some(gen_invokesuper), YARVINSN_leave => Some(gen_leave), + /* YARVINSN_getglobal => Some(gen_getglobal), YARVINSN_setglobal => Some(gen_setglobal), YARVINSN_anytostring => Some(gen_anytostring), @@ -6176,10 +6181,10 @@ impl CodegenGlobals { let leave_exit_code = gen_leave_exit(&mut ocb); - let stub_exit_code = gen_code_for_exit_from_stub(&mut ocb); + //let stub_exit_code = gen_code_for_exit_from_stub(&mut ocb); // Generate full exit code for C func - let cfunc_exit_code = gen_full_cfunc_return(&mut ocb); + //let cfunc_exit_code = gen_full_cfunc_return(&mut ocb); // Mark all code memory as executable cb.mark_all_executable(); @@ -6189,8 +6194,8 @@ impl CodegenGlobals { inline_cb: cb, outlined_cb: ocb, leave_exit_code: leave_exit_code, - stub_exit_code: stub_exit_code, - outline_full_cfunc_return_pos: cfunc_exit_code, + stub_exit_code: /*stub_exit_code*/CodePtr::from(1 as *mut u8), + outline_full_cfunc_return_pos: /*cfunc_exit_code*/CodePtr::from(1 as *mut u8), global_inval_patches: Vec::new(), inline_frozen_bytes: 0, method_codegen_table: HashMap::new(),