public static MosaType ToArray(this MosaType type, MosaArrayInfo info) { MosaType result = type.ToSZArray(); using (var arrayType = type.TypeSystem.Controller.MutateType(result)) { arrayType.TypeCode = MosaTypeCode.Array; arrayType.ArrayInfo = info; return result; } }
public static MosaType ToArray(this MosaType type, MosaArrayInfo info) { MosaType array = type.TypeSystem.GetTypeByName(type.TypeSystem.CorLib, "System", "Array"); MosaType result = type.TypeSystem.Controller.CreateType(array); using (var arrayType = type.TypeSystem.Controller.MutateType(result)) { // See Partition II 14.2 Arrays arrayType.Module = type.Module; arrayType.DeclaringType = type.DeclaringType; arrayType.Namespace = type.Namespace; arrayType.Name = type.Name; arrayType.HasOpenGenericParams = type.HasOpenGenericParams; arrayType.BaseType = array; arrayType.ElementType = type; arrayType.TypeCode = MosaTypeCode.Array; arrayType.ArrayInfo = info; AddArrayMethods(type.TypeSystem, result, arrayType, info); return result; } }
private static void AddArrayMethods(TypeSystem typeSystem, MosaType arrayType, MosaType.Mutator type, MosaArrayInfo info) { // Remove all methods & fields --> Since BaseType = System.Array, they're automatically inherited. type.Methods.Clear(); type.Fields.Clear(); // Add three array accessors as defined in standard (Get, Set, Address) // Also, constructor. uint rank = info.Rank; MosaMethod methodGet = typeSystem.Controller.CreateMethod(); using (var method = typeSystem.Controller.MutateMethod(methodGet)) { method.DeclaringType = arrayType; method.Name = "Get"; method.IsInternalCall = true; method.IsRTSpecialName = method.IsSpecialName = true; method.IsFinal = true; method.HasThis = true; List<MosaParameter> parameters = new List<MosaParameter>(); for (uint i = 0; i < rank; i++) { var indexParam = typeSystem.Controller.CreateParameter(); using (var mosaParameter = typeSystem.Controller.MutateParameter(indexParam)) { mosaParameter.Name = "index" + i; mosaParameter.ParameterAttributes = MosaParameterAttributes.In; mosaParameter.ParameterType = typeSystem.BuiltIn.I4; mosaParameter.DeclaringMethod = methodGet; } parameters.Add(indexParam); } method.Signature = new MosaMethodSignature(arrayType.ElementType, parameters); } type.Methods.Add(methodGet); MosaMethod methodSet = typeSystem.Controller.CreateMethod(); using (var method = typeSystem.Controller.MutateMethod(methodSet)) { method.DeclaringType = arrayType; method.Name = "Set"; method.IsInternalCall = true; method.IsRTSpecialName = method.IsSpecialName = true; method.IsFinal = true; method.HasThis = true; List<MosaParameter> parameters = new List<MosaParameter>(); for (uint i = 0; i < rank; i++) { var indexParam = typeSystem.Controller.CreateParameter(); using (var mosaParameter = typeSystem.Controller.MutateParameter(indexParam)) { mosaParameter.Name = "index" + i; mosaParameter.ParameterAttributes = MosaParameterAttributes.In; mosaParameter.ParameterType = typeSystem.BuiltIn.I4; mosaParameter.DeclaringMethod = methodSet; } parameters.Add(indexParam); } var valueParam = typeSystem.Controller.CreateParameter(); using (var mosaParameter = typeSystem.Controller.MutateParameter(valueParam)) { mosaParameter.Name = "value"; mosaParameter.ParameterAttributes = MosaParameterAttributes.In; mosaParameter.ParameterType = arrayType.ElementType; mosaParameter.DeclaringMethod = methodSet; } parameters.Add(valueParam); method.Signature = new MosaMethodSignature(typeSystem.BuiltIn.Void, parameters); } type.Methods.Add(methodSet); MosaMethod methodAdrOf = typeSystem.Controller.CreateMethod(); using (var method = typeSystem.Controller.MutateMethod(methodAdrOf)) { method.DeclaringType = arrayType; method.Name = "AddressOr"; method.IsInternalCall = true; method.IsRTSpecialName = method.IsSpecialName = true; method.IsFinal = true; method.HasThis = true; List<MosaParameter> parameters = new List<MosaParameter>(); for (uint i = 0; i < rank; i++) { var indexParam = typeSystem.Controller.CreateParameter(); using (var mosaParameter = typeSystem.Controller.MutateParameter(indexParam)) { mosaParameter.Name = "index" + i; mosaParameter.ParameterAttributes = MosaParameterAttributes.In; mosaParameter.ParameterType = typeSystem.BuiltIn.I4; mosaParameter.DeclaringMethod = methodAdrOf; } parameters.Add(indexParam); } method.Signature = new MosaMethodSignature(arrayType.ElementType.ToManagedPointer(), parameters); } type.Methods.Add(methodAdrOf); MosaMethod methodCtor = typeSystem.Controller.CreateMethod(); using (var method = typeSystem.Controller.MutateMethod(methodCtor)) { method.DeclaringType = arrayType; method.Name = ".ctor"; method.IsInternalCall = true; method.IsRTSpecialName = method.IsSpecialName = true; method.IsFinal = true; method.HasThis = true; List<MosaParameter> parameters = new List<MosaParameter>(); for (uint i = 0; i < rank; i++) { var lengthParam = typeSystem.Controller.CreateParameter(); using (var mosaParameter = typeSystem.Controller.MutateParameter(lengthParam)) { mosaParameter.Name = "length" + i; mosaParameter.ParameterAttributes = MosaParameterAttributes.In; mosaParameter.ParameterType = typeSystem.BuiltIn.I4; mosaParameter.DeclaringMethod = methodCtor; } parameters.Add(lengthParam); } method.Signature = new MosaMethodSignature(typeSystem.BuiltIn.Void, parameters); } type.Methods.Add(methodCtor); }
private MosaType Load(TypeSig typeSig) { if (typeSig is LeafSig) { if (typeSig is TypeDefOrRefSig) { throw new AssemblyLoadException(); // Should have been loaded in MetadataLoader } else if (typeSig is GenericInstSig) { return(LoadGenericTypeInstanceSig((GenericInstSig)typeSig)); } else if (typeSig is GenericSig) { return(LoadGenericParam((GenericSig)typeSig)); } else if (typeSig is FnPtrSig) { MethodSig fnPtr = (MethodSig)((FnPtrSig)typeSig).MethodSig; MosaType returnType = GetType(fnPtr.RetType); List <MosaParameter> pars = new List <MosaParameter>(); for (int i = 0; i < fnPtr.Params.Count; i++) { var parameter = metadata.Controller.CreateParameter(); using (var mosaParameter = metadata.Controller.MutateParameter(parameter)) { mosaParameter.Name = "A_" + i; mosaParameter.ParameterAttributes = MosaParameterAttributes.In; mosaParameter.ParameterType = GetType(fnPtr.Params[i]); } pars.Add(parameter); } return(metadata.TypeSystem.ToFnPtr(new MosaMethodSignature(returnType, pars))); } else { throw new NotSupportedException(); } } else // Non-leaf signature { MosaType elementType = GetType(typeSig.Next); MosaType result; switch (typeSig.ElementType) { case ElementType.Ptr: result = elementType.ToUnmanagedPointer(); using (var ptrType = metadata.Controller.MutateType(result)) ptrType.UnderlyingObject = elementType.GetUnderlyingObject <UnitDesc <TypeDef, TypeSig> >().Clone(typeSig); break; case ElementType.ByRef: result = elementType.ToManagedPointer(); using (var ptrType = metadata.Controller.MutateType(result)) ptrType.UnderlyingObject = elementType.GetUnderlyingObject <UnitDesc <TypeDef, TypeSig> >().Clone(typeSig); break; case ElementType.CModReqd: case ElementType.CModOpt: result = metadata.Controller.CreateType(elementType); using (var modType = metadata.Controller.MutateType(result)) { modType.Modifier = GetType(((ModifierSig)typeSig).Modifier.ToTypeSig()); modType.UnderlyingObject = elementType.GetUnderlyingObject <UnitDesc <TypeDef, TypeSig> >().Clone(typeSig); modType.ElementType = elementType; } break; case ElementType.Pinned: result = elementType; // Pinned types are indicated in MosaLocal return(result); // Don't add again to controller case ElementType.SZArray: GetType(new GenericInstSig(szHelperSig, typeSig.Next)); GetType(new GenericInstSig(iListSig, typeSig.Next)); result = elementType.ToSZArray(); using (var arrayType = metadata.Controller.MutateType(result)) arrayType.UnderlyingObject = elementType.GetUnderlyingObject <UnitDesc <TypeDef, TypeSig> >().Clone(typeSig); metadata.Resolver.EnqueueForArrayResolve(result); return(result); case ElementType.Array: ArraySig array = (ArraySig)typeSig; MosaArrayInfo arrayInfo = new MosaArrayInfo(array.LowerBounds, array.Rank, array.Sizes); result = elementType.ToArray(arrayInfo); using (var arrayType = metadata.Controller.MutateType(result)) arrayType.UnderlyingObject = elementType.GetUnderlyingObject <UnitDesc <TypeDef, TypeSig> >().Clone(typeSig); break; default: throw new AssemblyLoadException(); } metadata.Controller.AddType(result); return(result); } }