Exemplo n.º 1
0
        /// <summary>
        /// Build an array of GenericDictionaryCell from a NativeParser stream that has the appropriate metadata
        /// Return null if there are no cells to describe
        /// </summary>
        internal unsafe static GenericDictionaryCell[] BuildDictionaryFromMetadataTokensAndContext(TypeBuilder typeBuilder, NativeParser parser, NativeFormatMetadataUnit nativeMetadataUnit, FixupCellMetadataResolver resolver)
        {
            uint parserStartOffset = parser.Offset;

            uint count = parser.GetSequenceCount();

            // An empty dictionary isn't interesting
            if (count == 0)
                return null;

            Debug.Assert(count > 0);
            TypeLoaderLogger.WriteLine("Parsing dictionary layout @ " + parserStartOffset.LowLevelToString() + " (" + count.LowLevelToString() + " entries)");

            GenericDictionaryCell[] dictionary = new GenericDictionaryCell[count];

            for (uint i = 0; i < count; i++)
            {
                MetadataFixupKind fixupKind = (MetadataFixupKind)parser.GetUInt8();
                Internal.Metadata.NativeFormat.Handle token = parser.GetUnsigned().AsHandle();
                Internal.Metadata.NativeFormat.Handle token2 = new Internal.Metadata.NativeFormat.Handle();

                switch (fixupKind)
                {
                    case MetadataFixupKind.GenericConstrainedMethod:
                    case MetadataFixupKind.NonGenericConstrainedMethod:
                    case MetadataFixupKind.NonGenericDirectConstrainedMethod:
                        token2 = parser.GetUnsigned().AsHandle();
                        break;
                }
                GenericDictionaryCell cell = CreateCellFromFixupKindAndToken(fixupKind, resolver, token, token2);
                cell.Prepare(typeBuilder);
                dictionary[i] = cell;
            }

            return dictionary;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Create a single cell to resolve based on a MetadataFixupKind, and the matching tokens
        /// </summary>
        internal static GenericDictionaryCell CreateCellFromFixupKindAndToken(MetadataFixupKind kind, FixupCellMetadataResolver metadata, Internal.Metadata.NativeFormat.Handle token, Internal.Metadata.NativeFormat.Handle token2)
        {
            GenericDictionaryCell cell;

            switch (kind)
            {
                case MetadataFixupKind.TypeHandle:
                    {
                        var type = metadata.GetType(token);
                        TypeLoaderLogger.WriteLine("TypeHandle: " + type.ToString());

                        cell = new TypeHandleCell() { Type = type };
                    }
                    break;

                case MetadataFixupKind.ArrayOfTypeHandle:
                    {
                        var type = metadata.GetType(token);
                        var arrayType = type.Context.GetArrayType(type);
                        TypeLoaderLogger.WriteLine("TypeHandle: " + arrayType.ToString());

                        cell = new TypeHandleCell() { Type = arrayType };
                    }
                    break;

                case MetadataFixupKind.VirtualCallDispatch:
                    {
                        var method = metadata.GetMethod(token);


                        var containingType = method.OwningType;
                        if (containingType.IsInterface)
                        {
                            ushort slot;
                            if (!LazyVTableResolver.TryGetInterfaceSlotNumberFromMethod(method, out slot))
                            {
                                Environment.FailFast("Unable to get interface slot while resolving InterfaceCall dictionary cell");
                            }

                            TypeLoaderLogger.WriteLine("InterfaceCall: " + containingType.ToString() + ", slot #" + ((int)slot).LowLevelToString());

                            cell = new InterfaceCallCell() { InterfaceType = containingType, Slot = (int)slot };
                        }
                        else
                        {
                            // TODO! Implement virtual dispatch cell creation
                            throw NotImplemented.ByDesign;
                        }
                    }
                    break;

                case MetadataFixupKind.MethodDictionary:
                    {
                        var genericMethod = metadata.GetMethod(token);
                        TypeLoaderLogger.WriteLine("MethodDictionary: " + genericMethod.ToString());

                        cell = new MethodDictionaryCell { GenericMethod = (InstantiatedMethod)genericMethod };
                    }
                    break;

                case MetadataFixupKind.GcStaticData:
                    {
                        var type = metadata.GetType(token);
                        var staticDataKind = StaticDataKind.Gc;
                        TypeLoaderLogger.WriteLine("StaticData (" + (staticDataKind == StaticDataKind.Gc ? "Gc" : "NonGc") + ": " + type.ToString());

                        cell = new StaticDataCell() { DataKind = staticDataKind, Type = type };
                    }
                    break;

                case MetadataFixupKind.NonGcStaticData:
                    {
                        var type = metadata.GetType(token);
                        var staticDataKind = StaticDataKind.NonGc;
                        TypeLoaderLogger.WriteLine("StaticData (" + (staticDataKind == StaticDataKind.Gc ? "Gc" : "NonGc") + ": " + type.ToString());

                        cell = new StaticDataCell() { DataKind = staticDataKind, Type = type };
                    }
                    break;

                case MetadataFixupKind.DirectGcStaticData:
                    {
                        var type = metadata.GetType(token);
                        var staticDataKind = StaticDataKind.Gc;
                        TypeLoaderLogger.WriteLine("Direct StaticData (" + (staticDataKind == StaticDataKind.Gc ? "Gc" : "NonGc") + ": " + type.ToString());

                        cell = new StaticDataCell() { DataKind = staticDataKind, Type = type, Direct = true };
                    }
                    break;

                case MetadataFixupKind.DirectNonGcStaticData:
                    {
                        var type = metadata.GetType(token);
                        var staticDataKind = StaticDataKind.NonGc;
                        TypeLoaderLogger.WriteLine("Direct StaticData (" + (staticDataKind == StaticDataKind.Gc ? "Gc" : "NonGc") + ": " + type.ToString());

                        cell = new StaticDataCell() { DataKind = staticDataKind, Type = type, Direct = true };
                    }
                    break;

                case MetadataFixupKind.UnwrapNullableType:
                    {
                        var type = metadata.GetType(token);
                        TypeLoaderLogger.WriteLine("UnwrapNullableType of: " + type.ToString());

                        cell = new UnwrapNullableTypeCell() { Type = (DefType)type };
                    }
                    break;

                case MetadataFixupKind.FieldLdToken:
                    {
                        var field = metadata.GetField(token);

                        TypeLoaderLogger.WriteLine("LdToken on: " + field.ToString());
                        IntPtr fieldName = TypeLoaderEnvironment.Instance.GetNativeFormatStringForString(field.Name);
                        cell = new FieldLdTokenCell() { FieldName = fieldName, ContainingType = field.OwningType };
                    }
                    break;

                case MetadataFixupKind.MethodLdToken:
                    {
                        var method = metadata.GetMethod(token);
                        TypeLoaderLogger.WriteLine("LdToken on: " + method.ToString());
                        var nativeFormatMethod = (TypeSystem.NativeFormat.NativeFormatMethod)method.GetTypicalMethodDefinition();

                        cell = new MethodLdTokenCell
                        {
                            Method = method,
                            MethodName = IntPtr.Zero,
                            MethodSignature = RuntimeMethodSignature.CreateFromMethodHandle(nativeFormatMethod.MetadataUnit.RuntimeModule, nativeFormatMethod.Handle.ToInt())
                        };
                    }
                    break;

                case MetadataFixupKind.TypeSize:
                    {
                        var type = metadata.GetType(token);
                        TypeLoaderLogger.WriteLine("TypeSize: " + type.ToString());

                        cell = new TypeSizeCell() { Type = type };
                    }
                    break;

                case MetadataFixupKind.FieldOffset:
                    {
                        var field = metadata.GetField(token);
                        TypeLoaderLogger.WriteLine("FieldOffset: " + field.ToString());

                        cell = new FieldOffsetCell() { Field = field };
                    }
                    break;

                case MetadataFixupKind.AllocateObject:
                    {
                        var type = metadata.GetType(token);
                        TypeLoaderLogger.WriteLine("AllocateObject on: " + type.ToString());

                        cell = new AllocateObjectCell { Type = type };
                    }
                    break;

                case MetadataFixupKind.DefaultConstructor:
                    {
                        var type = metadata.GetType(token);
                        TypeLoaderLogger.WriteLine("DefaultConstructor on: " + type.ToString());

                        cell = new DefaultConstructorCell { Type = type };
                    }
                    break;

                case MetadataFixupKind.TlsIndex:
                    {
                        var type = metadata.GetType(token);
                        TypeLoaderLogger.WriteLine("TlsIndex on: " + type.ToString());

                        cell = new TlsIndexCell { Type = type };
                    }
                    break;

                case MetadataFixupKind.TlsOffset:
                    {
                        var type = metadata.GetType(token);
                        TypeLoaderLogger.WriteLine("TlsOffset on: " + type.ToString());

                        cell = new TlsOffsetCell { Type = type };
                    }
                    break;

                case MetadataFixupKind.UnboxingStubMethod:
                    {
                        var method = metadata.GetMethod(token);
                        TypeLoaderLogger.WriteLine("Unboxing Stub Method: " + method.ToString());
                        if (method.OwningType.IsValueType)
                        {
                            // If an unboxing stub could exists, that's actually what we want
                            method = method.Context.ResolveGenericMethodInstantiation(true/* get the unboxing stub */, method.OwningType.GetClosestDefType(), method.NameAndSignature, method.Instantiation, IntPtr.Zero, false);
                        }

                        var nativeFormatMethod = (TypeSystem.NativeFormat.NativeFormatMethod)method.GetTypicalMethodDefinition();

                        cell = new MethodCell
                        {
                            Method = method,
                            MethodSignature = RuntimeMethodSignature.CreateFromMethodHandle(nativeFormatMethod.MetadataUnit.RuntimeModule, nativeFormatMethod.Handle.ToInt())
                        };
                    }
                    break;

                case MetadataFixupKind.Method:
                    {
                        var method = metadata.GetMethod(token);
                        TypeLoaderLogger.WriteLine("Method: " + method.ToString());
                        var nativeFormatMethod = (TypeSystem.NativeFormat.NativeFormatMethod)method.GetTypicalMethodDefinition();

                        cell = new MethodCell
                        {
                            Method = method,
                            MethodSignature = RuntimeMethodSignature.CreateFromMethodHandle(nativeFormatMethod.MetadataUnit.RuntimeModule, nativeFormatMethod.Handle.ToInt())
                        };
                    }
                    break;

                case MetadataFixupKind.CallableMethod:
                    {
                        var method = metadata.GetMethod(token);
                        TypeLoaderLogger.WriteLine("CallableMethod: " + method.ToString());
                        var nativeFormatMethod = (TypeSystem.NativeFormat.NativeFormatMethod)method.GetTypicalMethodDefinition();

                        cell = new MethodCell
                        {
                            ExactCallableAddressNeeded = true,
                            Method = method,
                            MethodSignature = RuntimeMethodSignature.CreateFromMethodHandle(nativeFormatMethod.MetadataUnit.RuntimeModule, nativeFormatMethod.Handle.ToInt())
                        };
                    }
                    break;

                case MetadataFixupKind.NonGenericDirectConstrainedMethod:
                    {
                        var constraintType = metadata.GetType(token);
                        var method = metadata.GetMethod(token2);
                        var constrainedMethodType = method.OwningType;
                        var constrainedMethodSlot = ComputeConstrainedMethodSlot(method);

                        TypeLoaderLogger.WriteLine("NonGenericDirectConstrainedMethod: " + constraintType.ToString() + " Method:" + method.ToString() + " Consisting of " + constrainedMethodType.ToString() + ", slot #" + constrainedMethodSlot.LowLevelToString());

                        cell = new NonGenericDirectConstrainedMethodCell()
                        {
                            ConstraintType = constraintType,
                            ConstrainedMethodType = constrainedMethodType,
                            ConstrainedMethodSlot = (int)constrainedMethodSlot
                        };
                    }
                    break;

                case MetadataFixupKind.NonGenericConstrainedMethod:
                    {
                        var constraintType = metadata.GetType(token);
                        var method = metadata.GetMethod(token2);
                        var constrainedMethodType = method.OwningType;
                        var constrainedMethodSlot = ComputeConstrainedMethodSlot(method);

                        TypeLoaderLogger.WriteLine("NonGenericConstrainedMethod: " + constraintType.ToString() + " Method:" + method.ToString() + " Consisting of " + constrainedMethodType.ToString() + ", slot #" + constrainedMethodSlot.LowLevelToString());

                        cell = new NonGenericConstrainedMethodCell()
                        {
                            ConstraintType = constraintType,
                            ConstrainedMethodType = constrainedMethodType,
                            ConstrainedMethodSlot = (int)constrainedMethodSlot
                        };
                    }
                    break;

                case MetadataFixupKind.GenericConstrainedMethod:
                    {
                        var constraintType = metadata.GetType(token);
                        var method = metadata.GetMethod(token2);
                        var nativeFormatMethod = (TypeSystem.NativeFormat.NativeFormatMethod)method.GetTypicalMethodDefinition();


                        TypeLoaderLogger.WriteLine("GenericConstrainedMethod: " + constraintType.ToString() + " Method " + method.ToString());

                        cell = new GenericConstrainedMethodCell()
                        {
                            ConstraintType = constraintType,
                            ConstrainedMethod = method,
                            MethodName = IntPtr.Zero,
                            MethodSignature = RuntimeMethodSignature.CreateFromMethodHandle(nativeFormatMethod.MetadataUnit.RuntimeModule, nativeFormatMethod.Handle.ToInt())
                        };
                    }
                    break;

                case MetadataFixupKind.IsInst:
                case MetadataFixupKind.CastClass:
                    {
                        var type = metadata.GetType(token);

                        TypeLoaderLogger.WriteLine("Casting on: " + type.ToString());

                        cell = new CastingCell { Type = type, Throwing = (kind == MetadataFixupKind.CastClass) };
                    }
                    break;

                case MetadataFixupKind.AllocateArray:
                    {
                        var type = metadata.GetType(token);

                        TypeLoaderLogger.WriteLine("AllocateArray on: " + type.ToString());

                        cell = new AllocateArrayCell { Type = type };
                    }
                    break;

                case MetadataFixupKind.CheckArrayElementType:
                    {
                        var type = metadata.GetType(token);

                        TypeLoaderLogger.WriteLine("CheckArrayElementType on: " + type.ToString());

                        cell = new CheckArrayElementTypeCell { Type = type };
                    }
                    break;

                case MetadataFixupKind.CallingConventionConverter_NoInstantiatingParam:
                case MetadataFixupKind.CallingConventionConverter_MaybeInstantiatingParam:
                case MetadataFixupKind.CallingConventionConverter_HasInstantiatingParam:
                    {
                        CallingConventionConverterKind converterKind;
                        switch (kind)
                        {
                            case MetadataFixupKind.CallingConventionConverter_NoInstantiatingParam:
                                converterKind = CallingConventionConverterKind.NoInstantiatingParam;
                                break;
                            case MetadataFixupKind.CallingConventionConverter_MaybeInstantiatingParam:
                                converterKind = CallingConventionConverterKind.MaybeInstantiatingParam;
                                break;
                            case MetadataFixupKind.CallingConventionConverter_HasInstantiatingParam:
                                converterKind = CallingConventionConverterKind.HasInstantiatingParam;
                                break;
                            default:
                                Environment.FailFast("Unknown converter kind");
                                throw new BadImageFormatException();
                        }

                        cell = new CallingConventionConverterCell
                        {
                            Flags = converterKind,
                            Signature = metadata.GetSignature(token),
                            MethodArgs = metadata.MethodInstantiation,
                            TypeArgs = metadata.TypeInstantiation
                        };

#if TYPE_LOADER_TRACE
                        TypeLoaderLogger.WriteLine("CallingConventionConverter on: ");
                        TypeLoaderLogger.WriteLine("     -> Flags: " + ((int)converterKind).LowLevelToString());
                        TypeLoaderLogger.WriteLine("     -> Signature: " + token.ToInt().LowLevelToString());
                        for (int i = 0; i < metadata.TypeInstantiation.Length; i++)
                            TypeLoaderLogger.WriteLine("     -> TypeArg[" + i.LowLevelToString() + "]: " + metadata.TypeInstantiation[i]);
                        for (int i = 0; i < metadata.MethodInstantiation.Length; i++)
                            TypeLoaderLogger.WriteLine("     -> MethodArg[" + i.LowLevelToString() + "]: " + metadata.MethodInstantiation[i]);
#endif
                    }
                    break;

                default:
                    Environment.FailFast("Unknown fixup kind");
                    // Throw here so that the compiler won't complain.
                    throw new BadImageFormatException();
            }

            return cell;
        }