Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
 public override void EncodePointer(MirrorBufferPtr address, MirrorBufferPtr value)
 {
     Marshal.WriteIntPtr(address.HostBuffer, value.DeviceBuffer.Pointer);
 }
Ejemplo n.º 3
0
        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);
            }
        }
Ejemplo n.º 4
0
 public override MirrorBufferPtr IndexPointer(MirrorBufferPtr pointer, int offset)
 {
     return(new MirrorBufferPtr(pointer.DeviceBuffer + offset, pointer.HostBuffer + offset, pointer.Size - offset));
 }