vm/op.go
func (o op) MarshalBinary() ([]byte, error) {
	buf := rbpool.Get()
	defer rbpool.Release(buf)

	// Write the code/opcode
	if err := binary.Write(buf, binary.LittleEndian, int64(o.OpType)); err != nil {
		return nil, errors.Wrap(err, "failed to marshal op to binary")
	}

	// If this has args, we need to encode the args
	tArg := reflect.TypeOf(o.uArg)
	hasArg := tArg != nil
	if hasArg {
		binary.Write(buf, binary.LittleEndian, int8(1))
	} else {
		binary.Write(buf, binary.LittleEndian, int8(0))
	}

	if hasArg {
		switch tArg.Kind() {
		case reflect.Int:
			binary.Write(buf, binary.LittleEndian, int64(2))
			binary.Write(buf, binary.LittleEndian, int64(o.uArg.(int)))
		case reflect.Int64:
			binary.Write(buf, binary.LittleEndian, int64(2))
			binary.Write(buf, binary.LittleEndian, int64(o.uArg.(int64)))
		case reflect.Slice:
			if tArg.Elem().Kind() != reflect.Uint8 {
				panic("Slice of what?")
			}
			binary.Write(buf, binary.LittleEndian, int64(5))
			binary.Write(buf, binary.LittleEndian, int64(len(o.uArg.([]byte))))
			for _, v := range o.uArg.([]byte) {
				binary.Write(buf, binary.LittleEndian, v)
			}
		case reflect.String:
			binary.Write(buf, binary.LittleEndian, int64(6))
			binary.Write(buf, binary.LittleEndian, int64(len(o.uArg.(string))))
			for _, v := range []byte(o.uArg.(string)) {
				binary.Write(buf, binary.LittleEndian, v)
			}
		default:
			panic("Unknown type " + tArg.String())
		}
	}

	v := o.comment
	hasComment := v != ""
	if hasComment {
		binary.Write(buf, binary.LittleEndian, int8(1))
		binary.Write(buf, binary.LittleEndian, v)
	} else {
		binary.Write(buf, binary.LittleEndian, int8(0))
	}

	return buf.Bytes(), nil
}
func (o op) MarshalBinary() ([]byte, error) {
	buf := rbpool.Get()
	defer rbpool.Release(buf)

	// Write the code/opcode
	if err := binary.Write(buf, binary.LittleEndian, int64(o.OpType)); err != nil {
		return nil, errors.Wrap(err, "failed to marshal op to binary")
	}

	// If this has args, we need to encode the args
	tArg := reflect.TypeOf(o.uArg)
	hasArg := tArg != nil
	if hasArg {
		binary.Write(buf, binary.LittleEndian, int8(1))
	} else {
		binary.Write(buf, binary.LittleEndian, int8(0))
	}

	if hasArg {
		switch tArg.Kind() {
		case reflect.Int:
			binary.Write(buf, binary.LittleEndian, int64(2))
			binary.Write(buf, binary.LittleEndian, int64(o.uArg.(int)))
		case reflect.Int64:
			binary.Write(buf, binary.LittleEndian, int64(2))
			binary.Write(buf, binary.LittleEndian, int64(o.uArg.(int64)))
		case reflect.Slice:
			if tArg.Elem().Kind() != reflect.Uint8 {
				panic("Slice of what?")
			}
			binary.Write(buf, binary.LittleEndian, int64(5))
			binary.Write(buf, binary.LittleEndian, int64(len(o.uArg.([]byte))))
			for _, v := range o.uArg.([]byte) {
				binary.Write(buf, binary.LittleEndian, v)
			}
		case reflect.String:
			binary.Write(buf, binary.LittleEndian, int64(6))
			binary.Write(buf, binary.LittleEndian, int64(len(o.uArg.(string))))
			for _, v := range []byte(o.uArg.(string)) {
				binary.Write(buf, binary.LittleEndian, v)
			}
		default:
			panic("Unknown type " + tArg.String())
		}
	}

	v := o.comment
	hasComment := v != ""
	if hasComment {
		binary.Write(buf, binary.LittleEndian, int8(1))
		binary.Write(buf, binary.LittleEndian, v)
	} else {
		binary.Write(buf, binary.LittleEndian, int8(0))
	}

	return buf.Bytes(), nil
}
// MarshalBinary is used to serialize an Op into a binary form. This
// is used to cache the ByteCode