vm/vm.go
func (vm *VM) Run(bc *ByteCode, vars Vars, output io.Writer) {
	if !vm.IsSupportedByteCodeVersion(bc) {
		panic(fmt.Sprintf(
			"error: ByteCode version %f no supported",
			bc.Version,
		))
	}

	st := vm.st

	if _, ok := output.(*bufio.Writer); !ok {
		output = bufio.NewWriter(output)
		defer output.(*bufio.Writer).Flush()
	}
	st.Reset()
	st.pc = bc
	st.output = output
	newvars := Vars(rvpool.Get())
	defer rvpool.Release(newvars)
	defer newvars.Reset()

	st.vars = newvars
	if fc := vm.functions; fc != nil {
		for k, v := range vm.functions {
			st.vars[k] = v
		}
	}

	if vars != nil {
		for k, v := range vars {
			st.vars[k] = v
		}
	}
	st.Loader = vm.Loader

	// This is the main loop
	for op := st.CurrentOp(); op.Type() != TXOPEnd; op = st.CurrentOp() {
		op.Call(st)
	}
}
func (vm *VM) Run(bc *ByteCode, vars Vars, output io.Writer) {
	if !vm.IsSupportedByteCodeVersion(bc) {
		panic(fmt.Sprintf(
			"error: ByteCode version %f no supported",
			bc.Version,
		))
	}

	st := vm.st

	if _, ok := output.(*bufio.Writer); !ok {
		output = bufio.NewWriter(output)
		defer output.(*bufio.Writer).Flush()
	}
	st.Reset()
	st.pc = bc
	st.output = output
	newvars := Vars(rvpool.Get())
	defer rvpool.Release(newvars)
	defer newvars.Reset()

	st.vars = newvars
	if fc := vm.functions; fc != nil {
		for k, v := range vm.functions {
			st.vars[k] = v
		}
	}

	if vars != nil {
		for k, v := range vars {
			st.vars[k] = v
		}
	}
	st.Loader = vm.Loader

	// This is the main loop
	for op := st.CurrentOp(); op.Type() != TXOPEnd; op = st.CurrentOp() {
		op.Call(st)
	}
}
// Run executes the given vm.ByteCode using the given variables. For historical
// reasons, it also allows re-executing the previous bytecode instructions
// given to a virtual machine, but this will probably be removed in the future