/// <summary> /// Loads all custom attributes From the assembly. /// </summary> /// <param name="module">The module to load attributes From.</param> /// <param name="modOffset">The module offset.</param> private void LoadCustomAttributes(IMetadataModule module, ModuleOffsets modOffset) { IMetadataProvider metadata = module.Metadata; TokenTypes token, owner = 0, maxAttrs = metadata.GetMaxTokenValue(TokenTypes.CustomAttribute); CustomAttributeRow car; List <CustomAttributeRow> attributes = new List <CustomAttributeRow>(); for (token = TokenTypes.CustomAttribute + 1; token <= maxAttrs; token++) { metadata.Read(token, out car); // Do we need to commit generic parameters? if (owner != car.ParentTableIdx) { // Yes, commit them to the last type if (0 != owner && 0 != attributes.Count) { SetAttributes(module, owner, attributes); attributes.Clear(); } owner = car.ParentTableIdx; } // Save this attribute attributes.Add(car); } // Set the generic parameters of the last type, if we have them if (0 != attributes.Count) { SetAttributes(module, owner, attributes); } }
/// <summary> /// Gets the types From module. /// </summary> /// <param name="module">The module.</param> /// <returns></returns> ReadOnlyRuntimeTypeListView ITypeSystem.GetTypesFromModule(IMetadataModule module) { if (null == module) { throw new ArgumentNullException(@"module"); } // Determine the offsets of the module ModuleOffsets offsets = GetModuleOffset(module); // Calculate the number of types defined in this module int count = ((int)(TokenTypes.RowIndexMask & module.Metadata.GetMaxTokenValue(TokenTypes.TypeDef)) - 1 + 0); // FIXME: (int)(TokenTypes.RowIndexMask & module.Metadata.GetMaxTokenValue(TokenTypes.TypeSpec))); return(new ReadOnlyRuntimeTypeListView(offsets.TypeOffset, count)); }
RuntimeMethod ITypeSystem.GetMethod(IMetadataModule scope, TokenTypes token) { if (null == scope) { throw new ArgumentNullException(@"scope"); } switch (TokenTypes.TableMask & token) { case TokenTypes.MethodDef: { ModuleOffsets offsets = GetModuleOffset(scope); return(_methods[offsets.MethodOffset + (int)(TokenTypes.RowIndexMask & token) - 1]); } case TokenTypes.MemberRef: { MemberRefRow row; scope.Metadata.Read(token, out row); RuntimeType type = this.ResolveTypeRef(scope, row.ClassTableIdx); string nameString; scope.Metadata.Read(row.NameStringIdx, out nameString); MethodSignature sig = (MethodSignature)Signature.FromMemberRefSignatureToken(scope.Metadata, row.SignatureBlobIdx); foreach (RuntimeMethod method in type.Methods) { if (method.Name != nameString) { continue; } if (!method.Signature.Matches(sig)) { continue; } return(method); } throw new MissingMethodException(type.Name, nameString); } case TokenTypes.MethodSpec: throw new NotImplementedException(); default: throw new NotSupportedException(); } }
/// <summary> /// Notifies the type system that a CIL module was loaded. /// </summary> /// <param name="module">The loaded module.</param> void ITypeSystem.AssemblyLoaded(IMetadataModule module) { Debug.Assert(null != module && ((null == _moduleOffsets && 0 == module.LoadOrder) || _moduleOffsets.Length == module.LoadOrder)); if (null == module) { throw new ArgumentNullException(@"result"); } if ((null == _moduleOffsets && 0 != module.LoadOrder) || (null != _moduleOffsets && module.LoadOrder < _moduleOffsets.Length)) { throw new ArgumentException(@"Module is late?"); } IMetadataProvider md = module.Metadata; if (module.LoadOrder >= _moduleOffsets.Length) { Array.Resize(ref _moduleOffsets, module.LoadOrder + 1); } ModuleOffsets modOffset = new ModuleOffsets( AdjustMetadataSpace(md, TokenTypes.Field, ref _fields), AdjustMetadataSpace(md, TokenTypes.MethodDef, ref _methods), AdjustMetadataSpace(md, TokenTypes.Param, ref _parameters), AdjustMetadataSpace(md, TokenTypes.TypeDef, ref _types) ); _moduleOffsets[module.LoadOrder] = modOffset; // Add space for methodspec and typespec members AdjustMetadataSpace(md, TokenTypes.MethodSpec, ref _methods); AdjustMetadataSpace(md, TokenTypes.TypeSpec, ref _types); // Load all types From the assembly into the type array LoadTypes(module, modOffset); // LoadTypeSpecs(module, modOffset.TypeOffset); // LoadMethods(module, modOffset.MethodOffset); LoadGenerics(module, modOffset.TypeOffset, modOffset.MethodOffset); //LoadFields(module, modOffset.FieldOffset); LoadParameters(module, modOffset.ParameterOffset); LoadCustomAttributes(module, modOffset); }
RuntimeField ITypeSystem.GetField(IMetadataModule scope, TokenTypes token) { if (null == scope) { throw new ArgumentNullException(@"scope"); } if (TokenTypes.Field != (TokenTypes.TableMask & token) && TokenTypes.MemberRef != (TokenTypes.TableMask & token)) { throw new ArgumentException(@"Invalid field token."); } if (TokenTypes.MemberRef == (TokenTypes.TableMask & token)) { MemberRefRow row; scope.Metadata.Read(token, out row); throw new NotImplementedException(); } ModuleOffsets offsets = GetModuleOffset(scope); int fieldIndex = (int)(token & TokenTypes.RowIndexMask) - 1; RuntimeField result = _fields[offsets.FieldOffset + fieldIndex]; return(result); }
/// <summary> /// Loads all types From the given metadata module. /// </summary> /// <param name="module">The metadata module to load the types From.</param> /// <param name="moduleOffsets">The offsets into the metadata arrays, of the current module.</param> private void LoadTypes(IMetadataModule module, ModuleOffsets moduleOffsets) { TokenTypes maxTypeDef, maxField, maxMethod, maxLayout, tokenLayout = TokenTypes.ClassLayout + 1; TypeDefRow typeDefRow, nextTypeDefRow = new TypeDefRow(); ClassLayoutRow layoutRow = new ClassLayoutRow(); IMetadataProvider md = module.Metadata; int size = 0x0, packing = 0; int typeOffset = moduleOffsets.TypeOffset; int methodOffset = moduleOffsets.MethodOffset; int fieldOffset = moduleOffsets.FieldOffset; RuntimeType rt; maxTypeDef = md.GetMaxTokenValue(TokenTypes.TypeDef); maxLayout = md.GetMaxTokenValue(TokenTypes.ClassLayout); if (TokenTypes.ClassLayout < maxLayout) { md.Read(tokenLayout, out layoutRow); } TokenTypes token = TokenTypes.TypeDef + 2; md.Read(token, out typeDefRow); do { /* * string name; * md.Read(typeDefRow.TypeNameIdx, out name); * Debug.WriteLine(name); */ if (token < maxTypeDef) { md.Read(token + 1, out nextTypeDefRow); maxField = nextTypeDefRow.FieldList; maxMethod = nextTypeDefRow.MethodList; } else { maxMethod = md.GetMaxTokenValue(TokenTypes.MethodDef) + 1; maxField = md.GetMaxTokenValue(TokenTypes.Field) + 1; } // Is this our layout info? if ((layoutRow.ParentTypeDefIdx + 1) == token) { size = layoutRow.ClassSize; packing = layoutRow.PackingSize; tokenLayout++; if (tokenLayout <= maxLayout) { md.Read(tokenLayout, out layoutRow); } } // Create and populate the runtime type rt = new CilRuntimeType(token, module, ref typeDefRow, maxField, maxMethod, packing, size); LoadMethods(module, rt, typeDefRow.MethodList, maxMethod, ref methodOffset); LoadFields(module, rt, typeDefRow.FieldList, maxField, ref fieldOffset); _types[typeOffset++] = rt; if (rtCallTypeAttribute == null) { if (rt.Name == "InternalCallTypeAttribute" && rt.Namespace == "Mosa.Runtime.Vm") { rtCallTypeAttribute = rt; } } packing = size = 0; typeDefRow = nextTypeDefRow; }while (token++ < maxTypeDef); }