pub(crate) fn eval_block(&mut self, block: &Block, slice: &[Value]) -> VMResult {
        match block {
            Block::Block(method, outer) => {
                let outer = self.cfp_from_frame(*outer).ep();
                self.stack_push(outer.self_value());
                self.stack.extend_from_slice(slice);
                self.invoke_block(*method, outer, &Args2::new(slice.len()))?
                    .handle(self)
            }
            Block::Proc(proc) => {
                self.stack_push(Value::nil());
                self.stack.extend_from_slice(slice);
                self.invoke_proc(*proc, None, &Args2::new(slice.len()))?
                    .handle(self)
            }
            Block::Sym(sym) => {
                self.stack.extend_from_slice(slice);
                self.invoke_sym_proc(*sym, &Args2::new(slice.len()))?
                    .handle(self)
            }
        }
    }
Evaluate the block with self_val of outer context, and given `args`.
ruruby/src/vm/executor/method.rs