public ConvertDelegateToMulticastInstruction(CodeLocationTag codeLocation, HighSsaRegister dest, HighSsaRegister src, TypeSpecMulticastDelegateTag mdgSpec) : base(codeLocation) { m_dest = dest; m_src = src; m_mdType = mdgSpec; }
public RloMethodConverter(TagRepository tagRepo, RloInstantiationParameters instParams, TypeSpecTag returnType, HighLocal instanceLocal, HighLocal[] args, HighLocal[] locals) { m_tagRepo = tagRepo; m_instParams = instParams; m_returnType = InstantiateType(returnType); List<HighLocal> mergedLocals = new List<HighLocal>(); if (instanceLocal != null) mergedLocals.Add(instanceLocal); mergedLocals.AddRange(args); mergedLocals.AddRange(locals); foreach (HighLocal local in mergedLocals) { HighLocal newLocal = new HighLocal(this.InstantiateType(local.Type), local.TypeOfType); m_translatedLocals.Add(local, newLocal); } if (instanceLocal != null) m_instanceLocal = m_translatedLocals[instanceLocal]; List<HighLocal> newArgs = new List<HighLocal>(); foreach (HighLocal arg in args) newArgs.Add(m_translatedLocals[arg]); List<HighLocal> newLocals = new List<HighLocal>(); foreach (HighLocal local in locals) newLocals.Add(m_translatedLocals[local]); m_args = newArgs.ToArray(); m_locals = newLocals.ToArray(); }
public AllocInstanceDelegateInstruction(CodeLocationTag codeLocation, TypeSpecTag type, HighSsaRegister dest, HighSsaRegister obj) : base(codeLocation) { m_type = type; m_dest = dest; m_object = obj; }
public GetRloFieldInfoInstruction(CodeLocationTag codeLocation, HighSsaRegister dest, TypeSpecTag type, uint fieldIndex, bool isStatic) : base(codeLocation) { m_dest = dest; m_type = type; m_fieldIndex = fieldIndex; m_isStatic = isStatic; }
public override TypeSpecTag Instantiate(TagRepository repo, TypeSpecTag[] typeParams, TypeSpecTag[] methodParams) { if (m_genericParamType.Value == TypeSpecGenericParamTypeTag.Values.Var) return typeParams[m_index]; else if (m_genericParamType.Value == TypeSpecGenericParamTypeTag.Values.MVar) return methodParams[m_index]; throw new Exception(); }
public HighSsaRegister(HighValueType valueType, TypeSpecTag type, object constValue) { m_valueType = valueType; m_type = type; m_constValue = constValue; if ((valueType == HighValueType.ConstantString || valueType == HighValueType.ConstantValue) && constValue == null) throw new ArgumentException("Missing value for constant SSA"); }
public HighMethod(HighMethod baseMethod, TagRepository repo, TypeSpecTag[] argTypes) { m_static = baseMethod.m_static; m_methodSignature = baseMethod.m_methodSignature.Instantiate(repo, argTypes); m_methodBody = baseMethod.m_methodBody; m_methodDeclTag = baseMethod.m_methodDeclTag; m_isInternal = baseMethod.m_isInternal; }
public ConversionType ResolveGenericVariantAssignableTo(TypeSpecTag from, TypeSpecTag to) { if (from == to) return ConversionType.Exact; TypeSpecClassTag fromGI = from as TypeSpecClassTag; TypeSpecClassTag toGI = to as TypeSpecClassTag; if (fromGI == null || toGI == null) return ConversionType.NotConvertible; HighTypeDef typeDef = m_compiler.GetTypeDef(fromGI.TypeName); if (fromGI.TypeName != toGI.TypeName) return ConversionType.NotConvertible; uint numParams = typeDef.NumGenericParameters; if (numParams != fromGI.ArgTypes.Length || numParams != toGI.ArgTypes.Length) throw new RpaCompileException("Generic parameter type mismatch"); if (typeDef.Semantics != TypeSemantics.Interface && typeDef.Semantics != TypeSemantics.Delegate) return ConversionType.NotConvertible; for (uint i = 0; i < numParams; i++) { TypeSpecTag fromParam = fromGI.ArgTypes[i]; TypeSpecTag toParam = fromGI.ArgTypes[i]; if (fromParam == toParam) continue; HighVariance variance = typeDef.GenericParameterVariance(i); switch (variance) { case HighVariance.None: // Invariant: Can't assign at all return ConversionType.NotConvertible; case HighVariance.Covariant: if (!IsReferenceType(fromParam) || !IsReferenceType(toParam) || ResolveRefAssignable(fromParam, toParam) == ConversionType.NotConvertible) return ConversionType.NotConvertible; break; case HighVariance.Contravariant: if (!IsReferenceType(fromParam) || !IsReferenceType(toParam) || ResolveRefAssignable(toParam, fromParam) == ConversionType.NotConvertible) return ConversionType.NotConvertible; break; default: throw new ArgumentException(); } } if (typeDef.Semantics == TypeSemantics.Interface) return ConversionType.InterfaceToInterface; if (typeDef.Semantics == TypeSemantics.Delegate) return ConversionType.ClassToClass; throw new ArgumentException(); }
public RloMethodBody(HighLocal instanceLocal, HighLocal[] args, HighLocal[] locals, TypeSpecTag returnType, HighRegion entryRegion, MethodSignatureTag methodSignature, MethodInstantiationPath instPath) { m_instanceLocal = instanceLocal; m_args = args; m_locals = locals; m_returnType = returnType; m_entryRegion = entryRegion; m_instantiationPath = instPath; m_methodSignature = methodSignature; }
private CliClass(CliClass baseClass, Compiler compiler, TypeSpecTag[] argTypes) { if (!baseClass.m_isCreated) throw new Exception("Can't instantiate an open class that hasn't been processed"); m_typeName = baseClass.m_typeName; m_parentClassSpec = (TypeSpecClassTag)baseClass.m_parentClassSpec.Instantiate(compiler.TagRepository, argTypes); m_parentClass = compiler.GetClosedClass(m_parentClassSpec); m_isSealed = baseClass.m_isSealed; m_isAbstract = baseClass.m_isAbstract; m_isStruct = baseClass.m_isStruct; m_typeSpec = (TypeSpecClassTag)compiler.TagRepository.InternTypeSpec(new TypeSpecClassTag(m_typeName, argTypes)); m_isCreated = baseClass.m_isCreated; m_numGenericParameters = baseClass.m_numGenericParameters; List<HighField> staticFields = new List<HighField>(); foreach (HighField fld in baseClass.m_staticFields) staticFields.Add(fld.Instantiate(compiler.TagRepository, argTypes)); m_staticFields = staticFields.ToArray(); List<HighMethod> methods = new List<HighMethod>(); foreach (HighMethod method in baseClass.m_methods) methods.Add(method.Instantiate(compiler.TagRepository, argTypes)); m_methods = methods.ToArray(); List<HighField> instanceFields = new List<HighField>(); foreach (HighField fld in baseClass.m_instanceFields) instanceFields.Add(fld.Instantiate(compiler.TagRepository, argTypes)); m_instanceFields = instanceFields.ToArray(); List<CliVtableSlot> vtableSlots = new List<CliVtableSlot>(); foreach (CliVtableSlot slot in baseClass.m_vtable) vtableSlots.Add(slot.Instantiate(compiler, argTypes)); m_vtable = vtableSlots.ToArray(); List<CliInterfaceImpl> interfaceImpls = new List<CliInterfaceImpl>(); foreach (CliInterfaceImpl ifcImpl in baseClass.m_interfaceImpls) interfaceImpls.Add(ifcImpl.Instantiate(compiler, argTypes)); m_interfaceImpls = interfaceImpls.ToArray(); List<TypeSpecClassTag> explicitInterfaces = new List<TypeSpecClassTag>(); foreach (TypeSpecClassTag ifc in baseClass.m_explicitInterfaceSpecs) explicitInterfaces.Add((TypeSpecClassTag)ifc.Instantiate(compiler.TagRepository, argTypes)); m_explicitInterfaceSpecs = explicitInterfaces.ToArray(); m_declTagToMethod = baseClass.m_declTagToMethod; m_declTagToVTableSlot = baseClass.m_declTagToVTableSlot; m_ifcToIfcSlot = baseClass.m_ifcToIfcSlot; m_nameToInstanceFieldSlot = baseClass.m_nameToInstanceFieldSlot; m_nameToStaticFieldSlot = baseClass.m_nameToStaticFieldSlot; }
private TypeSpecTag GetOrReturnTypeSpec(ref TypeSpecTag typeSpecTag, string typeName) { if (typeSpecTag == null) { TypeNameTag nameTag = new TypeNameTag("mscorlib", "System", typeName); nameTag = m_compiler.TagRepository.InternTypeName(nameTag); TypeSpecTag typeSpec = new TypeSpecClassTag(nameTag, new TypeSpecTag[0]); typeSpecTag = m_compiler.TagRepository.InternTypeSpec(typeSpec); } return typeSpecTag; }
public static TypeSpecClassTag Read(CatalogReader rpa, BinaryReader reader) { TypeNameTag typeNameTag = rpa.GetTypeName(reader.ReadUInt32()); uint numArgTypes = typeNameTag.NumGenericParameters; TypeSpecTag[] argTypes = new TypeSpecTag[numArgTypes]; for (uint i = 0; i < numArgTypes; i++) argTypes[i] = rpa.GetTypeSpec(reader.ReadUInt32()); return new TypeSpecClassTag(typeNameTag, argTypes); }
private CliInterface(HighTypeDef typeDef, TypeSpecClassTag typeSpec, TypeSpecTag[] genericParameters, TypeSpecClassTag[] parentInterfaces, HighClassVtableSlot[] slots, Dictionary<MethodDeclTag, uint> slotTagToCliSlot, Dictionary<MethodDeclTag, uint> slotTagToRealSlot, uint numRealSlots, TypeSpecClassTag[] interfaceImpls) { m_typeDef = typeDef; m_typeSpec = typeSpec; m_genericParameters = genericParameters; m_slots = slots; m_slotTagToCliSlot = slotTagToCliSlot; m_slotTagToRealSlot = slotTagToRealSlot; m_numRealSlots = numRealSlots; m_interfaceImpls = interfaceImpls; m_isCreated = true; }
public void GenerateFromTypeSpec(Compiler compiler, TypeSpecTag typeSpec, VTableGenerationCache vtCache) { List<MethodHandle> methodHandles; if (typeSpec is TypeSpecClassTag) methodHandles = GenerateVTableForClass(compiler, (TypeSpecClassTag)typeSpec); else if (typeSpec is TypeSpecBoxTag) methodHandles = GenerateVTableForBox(compiler, (TypeSpecBoxTag)typeSpec, vtCache); else if (typeSpec is TypeSpecDelegateTag) methodHandles = GenerateVTableForDelegate(compiler, (TypeSpecDelegateTag)typeSpec, vtCache); else if (typeSpec is TypeSpecArrayTag) methodHandles = GenerateVTableForArray(compiler, (TypeSpecArrayTag)typeSpec); else if (typeSpec is TypeSpecMulticastDelegateTag) methodHandles = GenerateVTableForMulticastDelegate(compiler, (TypeSpecMulticastDelegateTag)typeSpec, vtCache); else throw new ArgumentException("Invalid typespec to generate an array from"); List<MethodHandle> finalHandles = new List<MethodHandle>(); m_instrSlotToRealSlot = new Dictionary<uint, uint>(); uint realSlot = 0; uint instrSlot = 0; foreach (MethodHandle hdl in methodHandles) { if (hdl == null) { instrSlot++; continue; } finalHandles.Add(hdl); m_instrSlotToRealSlot.Add(instrSlot, realSlot); instrSlot++; realSlot++; } m_methods = finalHandles.ToArray(); }
private ConversionType ResolveInterfaceBasedOn(CliInterface ifc, TypeSpecTag to) { if (to == m_objectType) return ConversionType.InterfaceToObject; HighTypeDef typeDef = m_compiler.GetTypeDef(ifc.TypeSpec.TypeName); foreach (TypeSpecClassTag newIfc in ifc.InterfaceImpls2) { if (ResolveGenericVariantAssignableTo(newIfc, to) != ConversionType.NotConvertible) return ConversionType.InterfaceToInterface; } return ConversionType.NotConvertible; }
private ConversionType ResolveClassBasedOn(CliClass cls, TypeSpecTag to) { HighTypeDef typeDef = m_compiler.GetTypeDef(cls.TypeSpec.TypeName); foreach (CliInterfaceImpl newIfc in cls.InterfaceImpls) { if (ResolveGenericVariantAssignableTo(newIfc.Interface, to) != ConversionType.NotConvertible) return ConversionType.ClassToInterface; } if (cls.ParentClassSpec == null) return ConversionType.NotConvertible; if (cls.ParentClassSpec == to) return ConversionType.ClassToClass; return ResolveClassBasedOn(m_compiler.GetClosedClass(cls.ParentClassSpec), to); }
private bool IsReferenceType(TypeSpecTag fromParam) { return !m_compiler.TypeIsValueType(fromParam); }
private TypeSpecClassTag ArrayClassForSubscript(TypeSpecTag subscriptType) { if (m_compiler.TypeIsValueType(subscriptType)) { TypeSpecClassTag subscriptClass = (TypeSpecClassTag)subscriptType; if (subscriptClass.TypeName == m_nullableName) { if (subscriptClass.ArgTypes.Length != 1) throw new RpaCompileException("Malformed Nullable"); TypeSpecClassTag classTag = new TypeSpecClassTag(m_nullableSZArrayName, subscriptClass.ArgTypes); classTag = (TypeSpecClassTag)m_compiler.TagRepository.InternTypeSpec(classTag); return classTag; } else { TypeSpecClassTag classTag = new TypeSpecClassTag(m_valueSZArrayName, new TypeSpecTag[1] { subscriptType }); classTag = (TypeSpecClassTag)m_compiler.TagRepository.InternTypeSpec(classTag); return classTag; } } else { TypeSpecClassTag classTag = new TypeSpecClassTag(m_refSZArrayName, new TypeSpecTag[0]); classTag = (TypeSpecClassTag)m_compiler.TagRepository.InternTypeSpec(classTag); return classTag; } }
public HighMethod Instantiate(TagRepository compiler, TypeSpecTag[] argTypes) { return new HighMethod(this, compiler, argTypes); }
public override TypeSpecTag Instantiate(TagRepository repo, TypeSpecTag[] argTypes) { if (m_genericParamType.Value == TypeSpecGenericParamTypeTag.Values.Var) return argTypes[m_index]; return this; }
public TypeSpecClassTag(TypeNameTag typeNameTag, TypeSpecTag[] argTypes) { m_typeNameTag = typeNameTag; m_argTypes = argTypes; }
public override TypeSpecTag Instantiate(TagRepository repo, TypeSpecTag[] argTypes) { return this; }
public HighCatchHandler(TypeSpecTag catchType, HighRegion region) { m_catchType = catchType; m_region = region; }
public override TypeSpecTag Instantiate(TagRepository repo, TypeSpecTag[] typeParams, TypeSpecTag[] methodParams) { return this; }
public RloValueType(Compiler compiler, TypeSpecTag type, RloInstantiationParameters instParams) { m_typeSpec = type.Instantiate(compiler.TagRepository, instParams.TypeParams, instParams.MethodParams); }
public override TypeSpecTag Instantiate(TagRepository repo, TypeSpecTag[] argTypes) { if (m_argTypes.Length == 0) return this; List<TypeSpecTag> newArgTypes = new List<TypeSpecTag>(); foreach (TypeSpecTag argType in m_argTypes) newArgTypes.Add(argType.Instantiate(repo, argTypes)); TypeSpecClassTag newSpec = new TypeSpecClassTag(m_typeNameTag, newArgTypes.ToArray()); return repo.InternTypeSpec(newSpec); }
// Inspects a value for hashable fields. If the field is hashable, returns true with the stack containing // the field descension. private bool RecursiveFindHashableField(Compiler compiler, TypeSpecTag fieldSpec, Stack<HighField> fieldStack) { // If the field is a reference type, this is OK if (!compiler.TypeIsValueType(fieldSpec)) return true; CliClass cls = compiler.GetClosedClass((TypeSpecClassTag)fieldSpec); if (cls.InstanceFields.Length == 0) { TypeNameTag typeName = cls.TypeName; if (typeName.AssemblyName == "mscorlib" && typeName.ContainerType == null && typeName.TypeNamespace == "System" && typeName.NumGenericParameters == 0) { string tn = typeName.TypeName; if (tn == "Boolean" || tn == "Char" || tn == "SByte" || tn == "Int16" || tn == "Int32" || tn == "Int64" || tn == "IntPtr" || tn == "Byte" || tn == "UInt16" || tn == "UInt32" || tn == "UInt64" || tn == "UIntPtr") return true; } // Empty structs that aren't a built-in POD type can't be hashed return false; } if ((m_vtCache.GetClassPodFlags(compiler, cls) & VTableGenerationCache.PodFlags.HashCode) != VTableGenerationCache.PodFlags.None) return true; // See if the class has a GetHashCode override uint vtSlot = m_vtCache.GetGetHashCodeVTableSlot(compiler); if (cls.VTable[vtSlot].MethodIndex.Depth == 0) return true; foreach (HighField fld in cls.InstanceFields) { fieldStack.Push(fld); if (RecursiveFindHashableField(compiler, fld.Type, fieldStack)) return true; fieldStack.Pop(); } return false; }
public ConversionType ResolveRefAssignable(TypeSpecTag from, TypeSpecTag to) { if (from == to) return ConversionType.Exact; if (from is TypeSpecClassTag) { TypeSpecClassTag tFrom = (TypeSpecClassTag)from; HighTypeDef fromTypeDef = m_compiler.GetTypeDef(tFrom.TypeName); if (tFrom.ArgTypes.Length != 0) { if (fromTypeDef.Semantics == TypeSemantics.Delegate || fromTypeDef.Semantics == TypeSemantics.Interface) { ConversionType ct = ResolveGenericVariantAssignableTo(from, to); if (ct != ConversionType.NotConvertible) return ct; } } if (fromTypeDef.Semantics == TypeSemantics.Interface) { CliInterface fromIfc = m_compiler.GetClosedInterface(tFrom); return ResolveInterfaceBasedOn(fromIfc, to); } else { CliClass fromClass = m_compiler.GetClosedClass(tFrom); return ResolveClassBasedOn(fromClass, to); } } else if (from is TypeSpecArrayTag) { TypeSpecArrayTag cplxFrom = (TypeSpecArrayTag)from; TypeSpecTag subscriptFrom = cplxFrom.SubscriptType; if (!cplxFrom.IsSZArray) { if (to is TypeSpecClassTag) { TypeSpecClassTag toClass = (TypeSpecClassTag)to; TypeNameTag toName = toClass.TypeName; TypeSpecClassTag arrayClassType = m_arrayType; if (IsReferenceType(toClass)) return ResolveRefAssignable(arrayClassType, toClass); return ConversionType.NotConvertible; } if (!(to is TypeSpecArrayTag)) return ConversionType.NotConvertible; TypeSpecArrayTag cplxTo = (TypeSpecArrayTag)to; if (cplxFrom.Rank != cplxTo.Rank) return ConversionType.NotConvertible; for (uint i = 0; i < cplxFrom.Rank; i++) if (cplxFrom.LowBounds[i] != cplxTo.LowBounds[i]) return ConversionType.NotConvertible; TypeSpecTag subscriptTo = cplxTo.SubscriptType; if (subscriptFrom == subscriptTo) return ConversionType.ClassToClass; if (IsReferenceType(subscriptFrom) && IsReferenceType(subscriptTo) && ResolveRefAssignable(subscriptFrom, subscriptTo) != ConversionType.NotConvertible) return ConversionType.ClassToClass; return ConversionType.NotConvertible; } else { // SZArray if (to is TypeSpecClassTag) { TypeSpecClassTag toClass = (TypeSpecClassTag)to; TypeNameTag toName = toClass.TypeName; if (toClass.ArgTypes.Length == 1) { if (toName == m_icollectionName || toName == m_ienumerableName || toName == m_ilistName) { TypeSpecTag ifcSubscriptTo = toClass.ArgTypes[0]; if (IsReferenceType(subscriptFrom) && IsReferenceType(ifcSubscriptTo) && ResolveRefAssignable(subscriptFrom, ifcSubscriptTo) != ConversionType.NotConvertible) { if (toName == m_icollectionName) return ConversionType.ArrayToGenericCollection; if (toName == m_ienumerableName) return ConversionType.ArrayToGenericEnumerable; if (toName == m_ilistName) return ConversionType.ArrayToGenericList; throw new Exception(); } } } TypeSpecClassTag arrayClassType = ArrayClassForSubscript(subscriptFrom); if (IsReferenceType(toClass)) { ConversionType ct = ResolveRefAssignable(arrayClassType, toClass); if (ct != ConversionType.Exact) return ct; } return ConversionType.NotConvertible; } if (!(to is TypeSpecArrayTag)) return ConversionType.NotConvertible; TypeSpecArrayTag arrayFrom = (TypeSpecArrayTag)from; TypeSpecArrayTag arrayTo = (TypeSpecArrayTag)to; TypeSpecTag subscriptTo = arrayTo.SubscriptType; if (IsReferenceType(subscriptFrom) && ResolveRefAssignable(subscriptFrom, subscriptTo) != ConversionType.NotConvertible) return ConversionType.ClassToClass; if (subscriptFrom == subscriptTo) return ConversionType.ClassToClass; return ConversionType.NotConvertible; } } throw new ArgumentException(); }
public void Read(TagRepository rpa, CatalogReader catalog, HighMethodBodyParseContext methodBody, CodeLocationTag baseLocation, bool haveDebugInfo, BinaryReader reader) { m_catchType = catalog.GetTypeSpec(reader.ReadUInt32()); m_region = HighRegion.Read(rpa, catalog, methodBody, baseLocation, haveDebugInfo, reader); }
public RloInstantiationParameters(TypeSpecTag[] typeParams, TypeSpecTag[] methodParams) { m_typeParams = typeParams; m_methodParams = methodParams; }