private bool GetArrayValue(ClrType type, ulong addr, int index, out object result) { var componentType = type.ComponentType; // componentType being null is a dac bug which should only happen when we have an array of // value types, where we have never *actually* constructed one of the types. If there are // other dac bugs which cause this, we unfortunately cannot work around it. if (addr == 0 || componentType == null) { result = new ClrNullValue(m_heap); return(true); } if (index < 0 || index >= m_len) { throw new IndexOutOfRangeException(); } // Now construct the value based on the element type. if (componentType.ElementType == ClrElementType.Struct) { addr = type.GetArrayElementAddress(addr, index); result = new ClrObject(m_heap, componentType, addr, true); return(true); } else if (componentType.IsObjectReference) { addr = type.GetArrayElementAddress(addr, index); if (!m_heap.Runtime.ReadPointer(addr, out addr) || addr == 0) { result = new ClrNullValue(m_heap); return(true); } else { result = new ClrObject(m_heap, componentType, addr); return(true); } } else if (componentType.IsPrimitive) { result = new ClrPrimitiveValue(type.GetArrayElementValue(addr, index), componentType.ElementType); return(true); } result = null; return(false); }
public override bool TryGetMember(GetMemberBinder binder, out object result) { if (IsNull()) { result = new ClrNullValue(m_heap); return(true); } ClrInstanceField field = null; if (binder.IgnoreCase) { foreach (var inst in m_type.Fields) { if (inst.Name.Equals(binder.Name, StringComparison.CurrentCultureIgnoreCase)) { field = inst; break; } } } else { field = m_type.GetFieldByName(binder.Name); } if (field == null) { if (ClrDynamicClass.GetStaticField(m_heap, m_type, binder, out result)) { return(true); } throw new InvalidOperationException(string.Format("Type '{0}' does not contain a '{1}' field.", m_type.Name, binder.Name)); } if (field.IsPrimitive) { object value = field.GetValue(m_addr, m_inner); if (value == null) { result = new ClrNullValue(m_heap); } else { result = new ClrPrimitiveValue(value, field.ElementType); } return(true); } else if (field.IsValueClass) { ulong addr = field.GetAddress(m_addr, m_inner); result = new ClrObject(m_heap, field.Type, addr, true); return(true); } else if (field.ElementType == ClrElementType.String) { ulong addr = field.GetAddress(m_addr, m_inner); if (!m_heap.Runtime.ReadPointer(addr, out addr)) { result = new ClrNullValue(m_heap); return(true); } result = new ClrObject(m_heap, field.Type, addr); return(true); } else { object value = field.GetValue(m_addr, m_inner); if (value == null) { result = new ClrNullValue(m_heap); } else { result = new ClrObject(m_heap, field.Type, (ulong)value); } return(true); } }