diff --git a/Tests/SimpleDebugClient/Program.cs b/Tests/SimpleDebugClient/Program.cs index 866d9ce..b815ec1 100644 --- a/Tests/SimpleDebugClient/Program.cs +++ b/Tests/SimpleDebugClient/Program.cs @@ -38,6 +38,6 @@ internal class Program private static void Debugger_InterpreterStep(object? sender, InterpreterEntry e) { - + Console.WriteLine($"[Interpreter] {e}"); } } \ No newline at end of file diff --git a/UIX/Microsoft/Iris/Debug/BsonFormatter.cs b/UIX/Microsoft/Iris/Debug/BsonFormatter.cs index 560cfae..f31d10f 100644 --- a/UIX/Microsoft/Iris/Debug/BsonFormatter.cs +++ b/UIX/Microsoft/Iris/Debug/BsonFormatter.cs @@ -2,9 +2,7 @@ using Newtonsoft.Json.Bson; using Newtonsoft.Json.Linq; using System; -using System.Collections.Generic; using System.IO; -using System.Linq; using System.Runtime.Serialization; namespace Microsoft.Iris.Debug; @@ -40,29 +38,44 @@ internal class BsonFormatter : IFormatter public object Deserialize(Stream serializationStream) { - using JsonTextReader reader = new(new StreamReader(serializationStream)) + using BsonDataReader reader = new(serializationStream) { CloseInput = false }; - var package = (JArray)_serializer.Deserialize(reader); - - // If the type is accessible from the current domain, - // create an instance of it. - var typeName = package[0].Value(); - var type = Type.GetType(typeName); - if (type != null) - return package[1].ToObject(type, _serializer); - - return package[1]; + BsonPackage package = new(_serializer, reader); + return package.Object ?? package.SerializedObject; } public void Serialize(Stream serializationStream, object graph) { - using JsonTextWriter writer = new(new StreamWriter(serializationStream)); + using BsonDataWriter writer = new(serializationStream); _serializer.Serialize(writer, new[] { graph?.GetType().FullName, graph }); writer.Flush(); } + + private class BsonPackage + { + public BsonPackage(JsonSerializer serializer, JsonReader reader) + { + var package = (JObject)serializer.Deserialize(reader); + + TypeName = package["0"].Value(); + SerializedObject = (JObject)package["1"]; + + // If the type is accessible from the current domain, + // create an instance of it. + var type = Type.GetType(TypeName); + if (type != null) + Object = SerializedObject.ToObject(type, serializer); + } + + public string TypeName { get; set; } + + public JObject SerializedObject { get; set; } + + public object Object { get; set; } + } } internal class BsonFallbackConverter : JsonConverter @@ -70,20 +83,36 @@ internal class BsonFallbackConverter : JsonConverter public override bool CanConvert(Type objectType) { return !objectType.Attributes.HasFlag(System.Reflection.TypeAttributes.Serializable) - || objectType == typeof(uint) || objectType == typeof(ulong); + || objectType.IsEnum || objectType == typeof(uint) || objectType == typeof(ulong) + || objectType == typeof(Type); } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + public override object ReadJson(JsonReader reader, Type objectType, object jsonValue, JsonSerializer serializer) { - if (existingValue != null) + jsonValue = reader.Value; + if (objectType == reader.ValueType) + return jsonValue; + + if (objectType == typeof(uint)) + return BitConverter.ToUInt32((byte[])jsonValue, 0); + else if (objectType == typeof(ulong)) + return BitConverter.ToUInt64((byte[])jsonValue, 0); + else if (objectType.IsEnum) { - if (objectType == typeof(uint)) - return Convert.ToUInt32(existingValue); - else if (objectType == typeof(ulong)) - return Convert.ToUInt64(existingValue); + if (reader.ValueType == typeof(string)) + return Enum.Parse(objectType, (string)reader.Value); + + return Enum.ToObject(objectType, reader.Value); + } + else if (objectType == typeof(Type)) + { + if (jsonValue is not string typeName) + return null; + + return Type.GetType(typeName); } - return existingValue?.ToString(); + return jsonValue?.ToString(); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) diff --git a/UIX/Microsoft/Iris/Debug/Data/InterpreterEntry.cs b/UIX/Microsoft/Iris/Debug/Data/InterpreterEntry.cs index 005ad6a..26aca79 100644 --- a/UIX/Microsoft/Iris/Debug/Data/InterpreterEntry.cs +++ b/UIX/Microsoft/Iris/Debug/Data/InterpreterEntry.cs @@ -8,27 +8,24 @@ namespace Microsoft.Iris.Debug.Data; [Serializable] public class InterpreterEntry { - public InterpreterEntry(OpCode opCode, uint offset, string loadUri, params InterpreterObject[] args) + public InterpreterEntry() { } + + public InterpreterEntry(OpCode opCode, uint offset, string loadUri) { OpCode = opCode; Offset = offset; LoadUri = loadUri; - - if (args != null && args.Length > 0) - Parameters = args; - else - Parameters = new List(); } - public OpCode OpCode { get; } + public OpCode OpCode { get; set; } - public uint Offset { get; } + public uint Offset { get; set; } - public string LoadUri { get; } + public string LoadUri { get; set; } - public IList Parameters { get; } + public List Parameters { get; } = new(); - public IList ReturnValues { get; } = new List(); + public List ReturnValues { get; } = new(); public override string ToString() { diff --git a/UIX/Microsoft/Iris/Debug/Data/InterpreterObject.cs b/UIX/Microsoft/Iris/Debug/Data/InterpreterObject.cs index 143ee60..a931da3 100644 --- a/UIX/Microsoft/Iris/Debug/Data/InterpreterObject.cs +++ b/UIX/Microsoft/Iris/Debug/Data/InterpreterObject.cs @@ -1,5 +1,4 @@ using System; -using System.Runtime.Serialization; namespace Microsoft.Iris.Debug.Data; @@ -25,11 +24,13 @@ public class InterpreterObject TableIndex = tableIndex; } - public InterpreterObject(object value) : this(null, value?.GetType() ?? typeof(object), value, InstructionObjectSource.Dynamic) + public InterpreterObject(object value) : this(null, value?.GetType(), value, InstructionObjectSource.Dynamic) { } - public override string ToString() => $"{Type} {Value}"; + public InterpreterObject() { } + + public override string ToString() => string.Join(" ", Type?.Name, Value?.ToString() ?? "NULL"); } ///