public override MirrorBufferPtr AllocateBuffer(int size) { var dev = Context.AllocateMemory(size); allocatedBuffers.Add(dev); var host = Marshal.AllocHGlobal(size); var result = new MirrorBufferPtr(dev, host, size); pendingBuffers.Add(result); return(result); }
public override void EncodePointer(MirrorBufferPtr address, MirrorBufferPtr value) { Marshal.WriteIntPtr(address.HostBuffer, value.DeviceBuffer.Pointer); }
public override bool TryEncodePrimitive(ValueOrRefObject value, MirrorBufferPtr buffer) { var val = value.Object; if (val == null) { Marshal.WriteIntPtr(buffer.HostBuffer, IntPtr.Zero); return(true); } else if (val is IntPtr) { Marshal.WriteIntPtr(buffer.HostBuffer, (IntPtr)val); return(true); } else if (val is byte) { Marshal.WriteByte(buffer.HostBuffer, (byte)val); return(true); } else if (val is sbyte) { Marshal.WriteByte(buffer.HostBuffer, (byte)(sbyte)val); return(true); } else if (val is short) { Marshal.WriteInt16(buffer.HostBuffer, (short)val); return(true); } else if (val is ushort) { Marshal.WriteInt16(buffer.HostBuffer, (short)(ushort)val); return(true); } else if (val is int) { Marshal.WriteInt32(buffer.HostBuffer, (int)val); return(true); } else if (val is uint) { Marshal.WriteInt32(buffer.HostBuffer, (int)(uint)val); return(true); } else if (val is long) { Marshal.WriteInt64(buffer.HostBuffer, (long)val); return(true); } else if (val is ulong) { Marshal.WriteInt64(buffer.HostBuffer, (long)(ulong)val); return(true); } // TODO: handle other primitive types, e.g., floating-point numbers and delegates. else if (val is Array) { var arr = (Array)val; var arrType = val.GetType(); var elemType = ToClr(arrType.GetElementType()); bool refElements = false; if (elemType.IsReferenceType()) { elemType = elemType.MakePointerType(PointerKind.Box); refElements = true; } var elemSize = SizeOf(elemType); var totalElements = arr.Length; // Allocate a buffer for the array. var buf = AllocateBuffer(MetadataSize + arr.Rank * 8 + totalElements * elemSize); // Initialize the array's vtable. InitializeObject(buf, ToClr(arrType)); buf = IndexPointer(buf, MetadataSize); // Map the array to its encoded version. RegisterEncoded(value, buf); EncodePointer(buffer, buf); // Encode array dimensions. // FIXME: this logic is directly dependent on the GC interface. Can we abstract // over this in a reasonable way at the Flame.Llvm level? for (int i = 0; i < arr.Rank; i++) { Marshal.WriteInt64(buf.HostBuffer, arr.GetLongLength(i)); buf = IndexPointer(buf, 8); } // Encode array contents. foreach (var item in arr) { var elem = refElements ? ValueOrRefObject.Reference(item) : ValueOrRefObject.Value(item); Encode(elem, buf); buf = IndexPointer(buf, elemSize); } return(true); } else { return(false); } }
public override MirrorBufferPtr IndexPointer(MirrorBufferPtr pointer, int offset) { return(new MirrorBufferPtr(pointer.DeviceBuffer + offset, pointer.HostBuffer + offset, pointer.Size - offset)); }