private ulong GetFieldAddress(string fieldName, ClrElementType element, string typeName, out ClrType type) { if (IsNull) { throw new NullReferenceException(); } type = Type; ClrInstanceField field = type.GetFieldByName(fieldName); if (field == null) { throw new ArgumentException($"Type '{type.Name}' does not contain a field named '{fieldName}'"); } if (field.ElementType != element) { throw new InvalidOperationException($"Field '{type.Name}.{fieldName}' is not of type '{typeName}'."); } ulong address = ClrRuntime.IsObjectReference(ElementType) ? Object : Address; address = field.GetAddress(address, Interior); return(address); }
/// <summary> /// Gets an object reference field from ClrObject. Any field which is a subclass of System.Object /// </summary> /// <param name="fieldName">The name of the field to retrieve.</param> /// <returns></returns> public ClrObject GetObject(string fieldName) { if (IsNull) { throw new NullReferenceException(); } ClrType type = Type; ClrInstanceField field = type.GetFieldByName(fieldName); if (field == null) { throw new ArgumentException($"Type '{type.Name}' does not contain a field named '{fieldName}'"); } if (!field.IsObjectReference) { throw new ArgumentException($"Field '{type.Name}.{fieldName}' is not an object reference."); } ClrHeap heap = Type.Heap; ulong addr = ClrRuntime.IsObjectReference(ElementType) ? Object : Address; addr = field.GetAddress(addr, Interior); ulong obj; if (!heap.ReadPointer(addr, out obj)) { throw new MemoryReadException(addr); } return(new ClrObject(obj, heap.GetObjectType(obj))); }
/// <summary> /// Converts the value to a raw string. This method will throw an InvalidOperationException if the target value is not a string. /// </summary> /// <returns>The string contents of this value.</returns> public virtual string AsString() { if (ElementType != ClrElementType.String && (!ClrRuntime.IsObjectReference(ElementType) || !Type.IsString)) { throw new InvalidOperationException("Value is not a string."); } ulong str; if (!_runtime.ReadPointer(Address, out str)) { throw new MemoryReadException(Address); } if (str == 0) { return(null); } string result; if (!_runtime.ReadString(str, out result)) { throw new MemoryReadException(str); } return(result); }
/// <summary> /// Returns a ClrObject for this value. /// </summary> /// <returns>A ClrObject for this value. If the value is null, then ClrObject.IsNull will the true and ClrObject.Type /// will equal ClrHeap.ErrorType.</returns> public virtual ClrObject AsObject() { if (!ClrRuntime.IsObjectReference(ElementType)) { throw new InvalidOperationException("Value is not an object."); } if (IsNull) { throw new NullReferenceException(); } ClrHeap heap = Runtime.GetHeap(); ulong obj = Object; return(new ClrObject(obj, obj != 0 ? heap.GetObjectType(obj) : heap.NullType)); }
/// <summary> /// Retrieves a field from this value. /// </summary> /// <param name="name">The name of the field.</param> /// <returns>A ClrValue representing this field.</returns> public virtual ClrValue GetField(string name) { ClrElementType el = ElementType; if (ClrRuntime.IsPrimitive(el)) { // Primitives only have one field, named m_value. if (name != "m_value") { throw new ArgumentException(string.Format("Field '{0}' does not exist in type '{1}'.", name, Type.Name)); } // Getting m_value is the same as this ClrValue... return(this); } if (ClrRuntime.IsObjectReference(el) || !Interior) { return(AsObject().GetField(name)); } Debug.Assert(ClrRuntime.IsValueClass(el)); ulong address = Address; if (address == 0) { throw new NullReferenceException(); } ClrType type = Type; ClrInstanceField field = type.GetFieldByName(name); if (field == null) { throw new ArgumentException(string.Format("Field '{0}' does not exist in type '{1}'.", name, Type.Name)); } ulong result = field.GetAddress(address, Interior); return(new ClrValueImpl(_runtime, result, field)); }
/// <summary> /// ToString implementation. /// </summary> /// <returns>A string value of this type.</returns> public override string ToString() { ClrElementType element = ElementType; if (element == ClrElementType.String) { return(AsString()); } if (ClrRuntime.IsObjectReference(element)) { return(AsObject().Address.ToString("x")); } if (ClrRuntime.IsValueClass(ElementType)) { return($"{Type.Name} @{Address:x}"); } switch (element) { case ClrElementType.Boolean: return(AsBoolean().ToString()); case ClrElementType.Int8: case ClrElementType.UInt8: return(AsByte().ToString()); case ClrElementType.Char: return(AsChar().ToString()); case ClrElementType.UInt16: case ClrElementType.Int16: return(AsInt16().ToString()); case ClrElementType.Int32: case ClrElementType.UInt32: return(AsInt32().ToString()); case ClrElementType.Int64: case ClrElementType.UInt64: return(AsInt64().ToString()); case ClrElementType.Pointer: case ClrElementType.FunctionPointer: case ClrElementType.NativeInt: return(AsIntPtr().ToInt64().ToString("x")); case ClrElementType.NativeUInt: return(AsUIntPtr().ToUInt64().ToString("x")); case ClrElementType.Float: return(AsFloat().ToString()); case ClrElementType.Double: return(AsDouble().ToString()); default: throw new NotImplementedException(); } }