Beispiel #1
0
        private static object DeserializeInner(RuntimeTypeHandle[] runtimeTypeHandles, byte *buffer, long length)
        {
            byte *objectId = buffer + IntPtr.Size;

            while (objectId < buffer + length)
            {
                IntPtr typeHandle = IntPtr.Size == 8 ? runtimeTypeHandles[(int)*(long *)objectId].Value : runtimeTypeHandles[*(int *)objectId].Value;
                bool   isArray    = ((long)typeHandle & 0x2) == 0x2;

                var mt = (MethodTable *)typeHandle;
                if (isArray)
                {
                    mt = IntPtr.Size == 8 ? (MethodTable *)*(long *)(typeHandle + 6) : (MethodTable *)*(int *)(typeHandle + 6); // TODO: Is this correct for 32-bit?
                }

                long objectSize       = mt->BaseSize;
                var  flags            = mt->Flags;
                bool hasComponentSize = (flags & 0x80000000) == 0x80000000;

                if (hasComponentSize)
                {
                    var numComponents = (long)*(int *)(objectId + IntPtr.Size);
                    objectSize += numComponents * mt->ComponentSize;
                }

                bool containsPointerOrCollectible = (flags & 0x10000000) == 0x10000000 || (flags & 0x1000000) == 0x1000000;
                if (containsPointerOrCollectible)
                {
                    var entries = *(int *)((byte *)mt - IntPtr.Size);
                    if (entries < 0)
                    {
                        entries -= entries;
                    }

                    var slots = 1 + entries * 2;

                    var gcdesc = new GCDesc(buffer, (byte *)mt - (slots * IntPtr.Size), slots * IntPtr.Size);

                    if (IntPtr.Size == 8)
                    {
                        gcdesc.FixupObject64(objectId, objectSize);
                    }
                    else
                    {
                        gcdesc.FixupObject32(objectId, objectSize);
                    }
                }

                if (IntPtr.Size == 8)
                {
                    *(long *)objectId = (long)mt;
                }
                else
                {
                    *(int *)objectId = (int)mt;
                }

                objectId += objectSize + Padding(objectSize, IntPtr.Size);
            }

            var tmp = buffer + IntPtr.Size;

            return(Unsafe.Read <object>(&tmp));
        }