pub(crate) fn run_loop(&mut self) -> VMResult {
        let mut invoke_count = 0usize;
        debug_assert!(self.is_ruby_func());
        loop {
            match self.run_context_main(&mut invoke_count) {
                Ok(val) => {
                    // 'Returned from 'call'ed method/block.
                    self.unwind_frame();
                    #[cfg(feature = "trace")]
                    if !self.discard_val() {
                        eprintln!("<+++ Ok({:?})", val);
                    } else {
                        eprintln!("<+++ Ok");
                    }
                    return Ok(val);
                }
                Err(mut err) => {
                    match err.kind {
                        RubyErrorKind::BlockReturn => {
                            #[cfg(feature = "trace")]
                            eprintln!("<+++ BlockReturn({:?})", self.globals.val);
                            return Err(err);
                        }
                        RubyErrorKind::MethodReturn => {
                            // In the case of MethodReturn, returned value is to be saved in vm.globals.val.
                            loop {
                                if invoke_count == 0 {
                                    #[cfg(feature = "trace")]
                                    eprintln!("<+++ MethodReturn({:?})", self.globals.val);
                                    self.unwind_frame();
                                    return Err(err);
                                };
                                self.unwind_frame();
                                #[cfg(feature = "trace")]
                                eprintln!("<--- MethodReturn({:?})", self.globals.val);
                                invoke_count -= 1;
                                if self.iseq.is_method() {
                                    break;
                                }
                            }
                            let val = self.globals.val;
                            self.stack_push(val);
                            continue;
                        }
                        _ => {}
                    }
                    // Handle Exception.
                    loop {
                        let cur_pc = self.pc_offset();
                        let iseq = self.iseq;
                        if err.info.is_empty() || iseq.kind != ISeqKind::Block {
                            err.info
                                .push((iseq.source_info.clone(), iseq.get_loc(cur_pc)));
                        }
                        if let RubyErrorKind::Internal(msg) = &err.kind {
                            self.globals.show_err(&err);
                            err.show_all_loc();
                            unreachable!("{}", msg);
                        };
                        let catch = iseq.exception_table.iter().find(|x| x.include(cur_pc));
                        if let Some(entry) = catch {
                            // Exception raised inside of begin-end with rescue clauses.
                            self.set_pc(entry.dest);
                            match entry.ty {
                                ExceptionType::Rescue => self.clear_stack(),
                                _ => {}
                            };
                            let val = self
                                .globals
                                .from_exception(&err)
                                .unwrap_or(self.globals.val);
                            #[cfg(feature = "trace")]
                            eprintln!(":::: Exception({:?})", val);
                            self.stack_push(val);
                            break;
                        } else {
                            // Exception raised outside of begin-end.
                            if invoke_count == 0 {
                                self.unwind_frame();
                                #[cfg(feature = "trace")]
                                eprintln!("<+++ {:?}", err.kind);
                                return Err(err);
                            }
                            self.unwind_frame();
                            invoke_count -= 1;
                            #[cfg(feature = "trace")]
                            eprintln!("<--- {:?}", err.kind);
                        }
                    }
                }
            }
        }
    }
VM main loop.

This fn is called when a Ruby method/block is 'call'ed.
That means VM main loop is called recursively.

Be aware that this fn does not restore vm.iseq and vm.pc.
ruruby/src/vm/executor.rs