public final void marshal(
        ThreadContext context, InvocationBuffer buffer, IRubyObject parameter) {
      if (!(parameter instanceof Struct)) {
        throw context
            .getRuntime()
            .newTypeError(
                "wrong argument type "
                    + parameter.getMetaClass().getName()
                    + " (expected instance of FFI::Struct)");
      }

      IRubyObject memory = ((Struct) parameter).getMemory();
      if (!(memory instanceof AbstractMemory)) {
        throw context
            .getRuntime()
            .newTypeError("wrong struct memory type " + memory.getMetaClass().getName());
      }

      MemoryIO io = ((AbstractMemory) memory).getMemoryIO();
      if (io instanceof DirectMemoryIO) {
        if (io.isNull()) {
          throw context
              .getRuntime()
              .newRuntimeError("Cannot use a NULL pointer as a struct by value argument");
        }
        buffer.putStruct(((DirectMemoryIO) io).getAddress());
      } else if (io instanceof ArrayMemoryIO) {
        ArrayMemoryIO aio = (ArrayMemoryIO) io;
        buffer.putStruct(aio.array(), aio.arrayOffset());
      } else {
        throw context.getRuntime().newRuntimeError("Invalid struct memory");
      }
    }
 private static final void addBufferParameter(
     InvocationBuffer buffer, IRubyObject parameter, int flags) {
   ArrayMemoryIO memory = (ArrayMemoryIO) ((Buffer) parameter).getMemoryIO();
   buffer.putArray(
       memory.array(),
       memory.arrayOffset(),
       memory.arrayLength(),
       flags & bufferFlags((Buffer) parameter));
 }