/// <summary> /// Initializes a new instance of <see cref="MemberOperand"/>. /// </summary> /// <param name="field">The runtime field to reference.</param> /// <exception cref="System.ArgumentNullException"><paramref name="field"/> is null.</exception> public MemberOperand(RuntimeField field) : base(null, field.SignatureType, IntPtr.Zero) { if (field == null) throw new ArgumentNullException(@"field"); this.member = field; }
private void AllocateSpace(RuntimeField field, SectionKind section, int size, int alignment) { using (Stream stream = linker.Allocate(field.ToString(), section, size, alignment)) { if (field.RVA != 0) { InitializeStaticValueFromRVA(stream, size, field); } else { stream.WriteZeroBytes(size); } } }
/// <summary> /// Gets the size of the field. /// </summary> /// <param name="field">The field.</param> /// <returns></returns> int ITypeLayout.GetFieldSize(RuntimeField field) { var size = 0; if (fieldSizes.TryGetValue(field, out size)) { return size; } else { ResolveType(field.DeclaringType); } // If the field is another struct, we have to dig down and compute its size too. if (field.SignatureType.Type == CilElementType.ValueType) { size = ((ITypeLayout)this).GetTypeSize(field.DeclaringType); } else { size = GetMemorySize(field.SignatureType); } fieldSizes.Add(field, size); return size; }
/// <summary> /// Gets the size of the field. /// </summary> /// <param name="field">The field.</param> /// <returns></returns> int ITypeLayout.GetFieldOffset(RuntimeField field) { ResolveType(field.DeclaringType); var offset = 0; fieldOffets.TryGetValue(field, out offset); return offset; }
private void InitializeStaticValueFromRVA(Stream stream, int size, RuntimeField field) { using (Stream source = field.Module.MetadataModule.GetDataSection((long)field.RVA)) { byte[] data = new byte[size]; int wrote = source.Read(data, 0, size); if (wrote != size) throw new InvalidDataException(); // FIXME stream.Write(data, 0, size); } }
/// <summary> /// Allocates memory for the static field and initializes it. /// </summary> /// <param name="field">The field.</param> private void CreateStaticField(RuntimeField field) { Debug.Assert(field != null, @"No field given."); // Determine the size of the type & alignment requirements int size, alignment; architecture.GetTypeRequirements(field.SignatureType, out size, out alignment); size = (int)typeLayout.GetFieldSize(field); // The linker section to move this field into SectionKind section; // Does this field have an RVA? if (field.RVA != 0) { // FIXME: Move a static field into ROData, if it is read-only and can be initialized // using static analysis section = SectionKind.Data; } else { section = SectionKind.BSS; } this.AllocateSpace(field, section, size, alignment); }
/// <summary> /// Creates a new runtime member <see cref="Operand"/>. /// </summary> /// <param name="field">The field.</param> /// <returns></returns> public static Operand CreateRuntimeMember(RuntimeField field) { Operand operand = new Operand(field.SignatureType, OperandType.MemoryAddress | OperandType.RuntimeMember); operand.offset = IntPtr.Zero; operand.runtimeMember = field; return operand; }
/// <summary> /// Creates a new SymbolOperand for the given runtime field. /// </summary> /// <param name="runtimeField">The field to create a symbol operand for.</param> /// <returns>The created symbol operand.</returns> public static SymbolOperand FromField(RuntimeField runtimeField) { return new SymbolOperand(runtimeField.SignatureType, runtimeField.ToString()); }
/* field.Address */ /// <summary> /// Initializes a new instance of the <see cref="StaticFieldOperand"/> class. /// </summary> /// <param name="field">The field.</param> public StaticFieldOperand(RuntimeField field, IntPtr offset) : base(null, field.SignatureType, offset) { }
/// <summary> /// Patches the field. /// </summary> /// <param name="typeModule">The type module.</param> /// <param name="enclosingType">Type of the closed.</param> /// <param name="openField">The open field.</param> /// <returns></returns> RuntimeField IGenericTypePatcher.PatchField(ITypeModule typeModule, CilGenericType enclosingType, RuntimeField openField) { var openType = openField.DeclaringType as CilGenericType; var genericArguments = CloseGenericArguments(enclosingType, openType); var patchedType = GetType(openType, genericArguments); if (patchedType == null) { var typeToken = new Token(0xFE000000 | ++typeTokenCounter); var signatureToken = new Token(0xFD000000 | ++signatureTokenCounter); var sigtype = new TypeSigType(signatureToken, CilElementType.Var); var signature = new GenericInstSigType(sigtype, genericArguments); // FIXME: There has got to be a better way to do this... try { patchedType = new CilGenericType(enclosingType.Module, typeToken, openType.BaseGenericType, signature); } catch (Exception) { foreach (var module in typeModule.TypeSystem.TypeModules) { try { patchedType = new CilGenericType(module, typeToken, openType.BaseGenericType, signature); break; } catch (Exception) { ; } } } AddType(patchedType, genericArguments); } foreach (var field in patchedType.Fields) { if (field.Name == openField.Name) { return field; } } throw new MissingFieldException(); }
/// <summary> /// Patches the field. /// </summary> /// <param name="typeModule">The type module.</param> /// <param name="enclosingType">Type of the closed.</param> /// <param name="openField">The open field.</param> /// <returns></returns> RuntimeField IGenericTypePatcher.PatchField(ITypeModule typeModule, CilGenericType enclosingType, RuntimeField openField) { var openType = openField.DeclaringType as CilGenericType; var genericArguments = CloseGenericArguments(enclosingType, openType); var patchedType = GetPatchedType(openType, genericArguments); if (patchedType == null) { var typeToken = new Token(0xFE000000 | ++typeTokenCounter); var signatureToken = new Token(0xFD000000 | ++signatureTokenCounter); var sigtype = new TypeSigType(signatureToken, CilElementType.Var); var signature = new GenericInstSigType(sigtype, genericArguments); patchedType = new CilGenericType(enclosingType.InstantiationModule, typeToken, openType.BaseGenericType, signature); AddPatchedType(openType, genericArguments, patchedType); } foreach (var field in patchedType.Fields) { if (field.Name == openField.Name) { return field; } } throw new MissingFieldException(); }
void ICompilationScheduler.TrackFieldReferenced(RuntimeField field) { if (compileAllMethods) CompileType(field.DeclaringType); }
/* field.Address */ /// <summary> /// Initializes a new instance of the <see cref="ObjectFieldOperand"/> class. /// </summary> /// <param name="objectInstance">The operand, representing the object instance.</param> /// <param name="field">The referenced field.</param> public ObjectFieldOperand(Operand objectInstance, RuntimeField field, IntPtr offset) : base(null, field.SignatureType, offset) { }