private static NativeObject BuildDebuggableObject(XaeiOSObject xaeiosObject, VTable vtable, IntRef fieldCounter) { NativeObject debuggableObject = new NativeObject(); // add fields from base class // update field counter along the way so that we know which slots correspond to which field names if (vtable != GetSystemObjectVTable()) { debuggableObject[DebugBaseKey] = var.Cast<NativeObject>(BuildDebuggableObject( xaeiosObject, vtable.BaseVTable, fieldCounter )); } // retreive debug information for class through vtable VTableDebugInfo debugInfo = vtable.DebugInfo; // apply debug information to object instance { debuggableObject["FullName"] = var.Cast<string>(debugInfo.FullName); // fields NativeArray<string> fieldNames = debugInfo.Fields; for (int i = 0; i < fieldNames.Length; i++) { debuggableObject[fieldNames[i]] = xaeiosObject[fieldCounter.Value + i]; } fieldCounter.Value += fieldNames.Length; } return debuggableObject; }
private static VTable GetSystemObjectVTable() { if (_object == null) { _object = XaeiOSObject.ToXaeiOSObject(new object()); } return _object.VTable; }
private static unsafe object TryCast(XaeiOSObject obj, VTable typeVTable) { return Cast(obj, typeVTable, false); }
private static unsafe object Cast(XaeiOSObject obj, VTable typeVtable, bool throwError) { if (obj == null) { if (throwError) { throw new InvalidCastException("Cannot cast null"); } else { return null; } } if (typeVtable == null) { throw new ExecutionEngineException("Cannot cast to null type"); } bool isInterface = (typeVtable.Flags & VTableFlags.IsInterface) != 0; VTable vtable = obj.VTable; if (vtable == null) { throw new ExecutionEngineException("Could not find vtable for object"); } while (vtable != null) { if (vtable == typeVtable) { return obj; } else if (isInterface && ImplementsInterface(vtable, typeVtable)) { return obj; } else { vtable = vtable.BaseVTable; } } if (throwError) { throw new InvalidCastException(string.NativeConcat(new string[] { "Cannot cast ", vtable.Class.FullName, " to type ", typeVtable.Class.FullName })); } else { return null; } }