internal static GenericDictionaryCell ParseAndCreateCell(NativeLayoutInfoLoadContext nativeLayoutInfoLoadContext, ref NativeParser parser) { GenericDictionaryCell cell; var kind = parser.GetFixupSignatureKind(); switch (kind) { case FixupSignatureKind.TypeHandle: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("TypeHandle: " + type.ToString()); cell = new TypeHandleCell() { Type = type }; } break; case FixupSignatureKind.InterfaceCall: { var interfaceType = nativeLayoutInfoLoadContext.GetType(ref parser); var slot = parser.GetUnsigned(); TypeLoaderLogger.WriteLine("InterfaceCall: " + interfaceType.ToString() + ", slot #" + slot.LowLevelToString()); cell = new InterfaceCallCell() { InterfaceType = interfaceType, Slot = (int)slot }; } break; case FixupSignatureKind.MethodDictionary: { var genericMethod = nativeLayoutInfoLoadContext.GetMethod(ref parser); Debug.Assert(genericMethod.Instantiation.Length > 0); TypeLoaderLogger.WriteLine("MethodDictionary: " + genericMethod.ToString()); cell = new MethodDictionaryCell { GenericMethod = (InstantiatedMethod)genericMethod }; } break; case FixupSignatureKind.StaticData: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); StaticDataKind staticDataKind = (StaticDataKind)parser.GetUnsigned(); TypeLoaderLogger.WriteLine("StaticData (" + (staticDataKind == StaticDataKind.Gc ? "Gc" : "NonGc") + ": " + type.ToString()); cell = new StaticDataCell() { DataKind = staticDataKind, Type = type }; } break; case FixupSignatureKind.UnwrapNullableType: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("UnwrapNullableType of: " + type.ToString()); cell = new UnwrapNullableTypeCell() { Type = (DefType)type }; } break; case FixupSignatureKind.FieldLdToken: { NativeParser ldtokenSigParser = parser.GetParserFromRelativeOffset(); var type = nativeLayoutInfoLoadContext.GetType(ref ldtokenSigParser); IntPtr fieldNameSig = ldtokenSigParser.Reader.OffsetToAddress(ldtokenSigParser.Offset); TypeLoaderLogger.WriteLine("LdToken on: " + type.ToString() + "." + ldtokenSigParser.GetString()); cell = new FieldLdTokenCell() { FieldName = fieldNameSig, ContainingType = type }; } break; case FixupSignatureKind.MethodLdToken: { NativeParser ldtokenSigParser = parser.GetParserFromRelativeOffset(); IntPtr methodNameSigPtr; IntPtr methodSigPtr; var method = nativeLayoutInfoLoadContext.GetMethod(ref ldtokenSigParser, out methodNameSigPtr, out methodSigPtr); TypeLoaderLogger.WriteLine("LdToken on: " + method.OwningType.ToString() + "::" + method.NameAndSignature.Name); cell = new MethodLdTokenCell { Method = method, MethodName = methodNameSigPtr, MethodSignature = RuntimeMethodSignature.CreateFromNativeLayoutSignature(methodSigPtr) }; } break; case FixupSignatureKind.TypeSize: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("TypeSize: " + type.ToString()); cell = new TypeSizeCell() { Type = type }; } break; case FixupSignatureKind.FieldOffset: { var type = (DefType)nativeLayoutInfoLoadContext.GetType(ref parser); uint ordinal = parser.GetUnsigned(); TypeLoaderLogger.WriteLine("FieldOffset on: " + type.ToString()); cell = new FieldOffsetCell() { Ordinal = ordinal, ContainingType = type }; } break; case FixupSignatureKind.VTableOffset: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); var vtableSlot = parser.GetUnsigned(); TypeLoaderLogger.WriteLine("VTableOffset on: " + type.ToString() + ", slot: " + vtableSlot.LowLevelToString()); cell = new VTableOffsetCell() { ContainingType = type, VTableSlot = vtableSlot }; } break; case FixupSignatureKind.AllocateObject: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("AllocateObject on: " + type.ToString()); cell = new AllocateObjectCell { Type = type }; } break; case FixupSignatureKind.DefaultConstructor: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("DefaultConstructor on: " + type.ToString()); cell = new DefaultConstructorCell { Type = type }; } break; case FixupSignatureKind.TlsIndex: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("TlsIndex on: " + type.ToString()); cell = new TlsIndexCell { Type = type }; } break; case FixupSignatureKind.TlsOffset: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("TlsOffset on: " + type.ToString()); cell = new TlsOffsetCell { Type = type }; } break; case FixupSignatureKind.Method: { IntPtr methodSigPtr; IntPtr methodNameSigPtr; var method = nativeLayoutInfoLoadContext.GetMethod(ref parser, out methodNameSigPtr, out methodSigPtr); TypeLoaderLogger.WriteLine("Method: " + method.ToString()); cell = new MethodCell { Method = method, MethodSignature = RuntimeMethodSignature.CreateFromNativeLayoutSignature(methodSigPtr) }; } break; case FixupSignatureKind.NonGenericDirectConstrainedMethod: { var constraintType = nativeLayoutInfoLoadContext.GetType(ref parser); var constrainedMethodType = nativeLayoutInfoLoadContext.GetType(ref parser); var constrainedMethodSlot = parser.GetUnsigned(); TypeLoaderLogger.WriteLine("NonGenericDirectConstrainedMethod: " + constraintType.ToString() + " Method " + constrainedMethodType.ToString() + ", slot #" + constrainedMethodSlot.LowLevelToString()); cell = new NonGenericDirectConstrainedMethodCell() { ConstraintType = constraintType, ConstrainedMethodType = constrainedMethodType, ConstrainedMethodSlot = (int)constrainedMethodSlot }; } break; case FixupSignatureKind.NonGenericConstrainedMethod: { var constraintType = nativeLayoutInfoLoadContext.GetType(ref parser); var constrainedMethodType = nativeLayoutInfoLoadContext.GetType(ref parser); var constrainedMethodSlot = parser.GetUnsigned(); TypeLoaderLogger.WriteLine("NonGenericConstrainedMethod: " + constraintType.ToString() + " Method " + constrainedMethodType.ToString() + ", slot #" + constrainedMethodSlot.LowLevelToString()); cell = new NonGenericConstrainedMethodCell() { ConstraintType = constraintType, ConstrainedMethodType = constrainedMethodType, ConstrainedMethodSlot = (int)constrainedMethodSlot }; } break; case FixupSignatureKind.GenericConstrainedMethod: { var constraintType = nativeLayoutInfoLoadContext.GetType(ref parser); NativeParser ldtokenSigParser = parser.GetParserFromRelativeOffset(); IntPtr methodNameSigPtr; IntPtr methodSigPtr; var method = nativeLayoutInfoLoadContext.GetMethod(ref ldtokenSigParser, out methodNameSigPtr, out methodSigPtr); TypeLoaderLogger.WriteLine("GenericConstrainedMethod: " + constraintType.ToString() + " Method " + method.OwningType.ToString() + "::" + method.NameAndSignature.Name); cell = new GenericConstrainedMethodCell() { ConstraintType = constraintType, ConstrainedMethod = method, MethodName = methodNameSigPtr, MethodSignature = RuntimeMethodSignature.CreateFromNativeLayoutSignature(methodSigPtr) }; } break; case FixupSignatureKind.IsInst: case FixupSignatureKind.CastClass: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("Casting on: " + type.ToString()); cell = new CastingCell { Type = type, Throwing = (kind == FixupSignatureKind.CastClass) }; } break; case FixupSignatureKind.AllocateArray: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("AllocateArray on: " + type.ToString()); cell = new AllocateArrayCell { Type = type }; } break; case FixupSignatureKind.CheckArrayElementType: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("CheckArrayElementType on: " + type.ToString()); cell = new CheckArrayElementTypeCell { Type = type }; } break; case FixupSignatureKind.CallingConventionConverter: { NativeFormat.CallingConventionConverterKind flags = (NativeFormat.CallingConventionConverterKind)parser.GetUnsigned(); NativeParser sigParser = parser.GetParserFromRelativeOffset(); IntPtr signature = sigParser.Reader.OffsetToAddress(sigParser.Offset); #if TYPE_LOADER_TRACE TypeLoaderLogger.WriteLine("CallingConventionConverter on: "); TypeLoaderLogger.WriteLine(" -> Flags: " + ((int)flags).LowLevelToString()); TypeLoaderLogger.WriteLine(" -> Signature: " + signature.LowLevelToString()); for (int i = 0; !nativeLayoutInfoLoadContext._typeArgumentHandles.IsNull && i < nativeLayoutInfoLoadContext._typeArgumentHandles.Length; i++) TypeLoaderLogger.WriteLine(" -> TypeArg[" + i.LowLevelToString() + "]: " + nativeLayoutInfoLoadContext._typeArgumentHandles[i]); for (int i = 0; !nativeLayoutInfoLoadContext._methodArgumentHandles.IsNull && i < nativeLayoutInfoLoadContext._methodArgumentHandles.Length; i++) TypeLoaderLogger.WriteLine(" -> MethodArg[" + i.LowLevelToString() + "]: " + nativeLayoutInfoLoadContext._methodArgumentHandles[i]); #endif cell = new CallingConventionConverterCell { Flags = flags, Signature = RuntimeMethodSignature.CreateFromNativeLayoutSignature(signature), MethodArgs = nativeLayoutInfoLoadContext._methodArgumentHandles, TypeArgs = nativeLayoutInfoLoadContext._typeArgumentHandles }; } break; case FixupSignatureKind.NotYetSupported: TypeLoaderLogger.WriteLine("Valid dictionary entry, but not yet supported by the TypeLoader!"); throw new TypeBuilder.MissingTemplateException(); default: parser.ThrowBadImageFormatException(); cell = null; break; } return cell; }
/// <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; }