Пример #1
0
        public override IReadOnlyDictionary <IField, ValueOrRefObject> GetFieldValues(ValueOrRefObject value)
        {
            var t       = value.Object.GetType();
            var results = new Dictionary <IField, ValueOrRefObject>();

            foreach (var field in t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                var flameField = Assembly.Resolve(Assembly.Definition.MainModule.ImportReference(field));
                var val        = field.GetValue(value.Object);
                results[flameField] = flameField.FieldType.IsPointerType(PointerKind.Box)
                    ? ValueOrRefObject.Reference(val)
                    : ValueOrRefObject.Value(val);
            }
            return(results);
        }
Пример #2
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);
            }
        }
Пример #3
0
 public override ValueOrRefObject LoadBoxPointer(ValueOrRefObject pointer)
 {
     return(ValueOrRefObject.Value(pointer.Object));
 }