pub(super) fn exec_native(
        &mut self,
        func: &BuiltinFunc,
        _method_id: FnId,
        _name: IdentId,
        args: &Args2,
    ) -> Result<Value, RubyError> {
        #[cfg(feature = "perf")]
        self.globals.perf.get_perf(Perf::EXTERN);

        #[cfg(feature = "trace")]
        {
            println!(
                "+++> BuiltinFunc self:{:?} name:{:?}",
                (self.sp() - args.len() - 1)[0],
                _name
            );
        }

        #[cfg(feature = "perf-method")]
        self.globals.methods.inc_counter(_method_id);

        let iseq = self.iseq;
        let pc = self.pc;
        let cfp = self.cfp;
        self.save_next_pc();
        self.push_native_frame(args.len());

        let temp_len = self.temp_len();
        let res = func(self, self.self_value(), args);
        self.temp_stack.truncate(temp_len);

        self.unwind_native_frame(cfp);
        self.pc = pc;
        self.iseq = iseq;

        #[cfg(feature = "trace")]
        println!("<+++ {:?}", res);
        match res {
            Ok(val) => Ok(val),
            Err(err) => {
                if err.is_block_return() {
                    let val = self.globals.val;
                    Ok(val)
                } else {
                    Err(err)
                }
            }
        }
    }
Invoke the method defined by Rust fn and push the returned value on the stack.
ruruby/src/vm/executor/method.rs