diff --git a/Tests/SimpleDebugClient/Program.cs b/Tests/SimpleDebugClient/Program.cs index 0b63783..920bea0 100644 --- a/Tests/SimpleDebugClient/Program.cs +++ b/Tests/SimpleDebugClient/Program.cs @@ -8,7 +8,7 @@ internal class Program { static IDebuggerClient? Debugger { get; set; } - static void Main(string[] args) + static int Main(string[] args) { string connectionString = args.Length >= 2 ? args[1] : "tcp://127.0.0.1:5556"; @@ -17,10 +17,12 @@ internal class Program Debugger = new ZmqDebuggerClient(connectionString); Debugger.DispatcherStep += Debugger_DispatcherStep; - //Debugger.InterpreterStep += Debugger_InterpreterStep; + Debugger.InterpreterStep += Debugger_InterpreterStep; Console.WriteLine("Listening for debug messages. Press Ctrl-C to exit."); Console.ReadLine(); + + return 0; } private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e) diff --git a/UIX/Microsoft/Iris/Debug/Data/InterpreterEntry.cs b/UIX/Microsoft/Iris/Debug/Data/InterpreterEntry.cs index 71ac010..ac6d4f9 100644 --- a/UIX/Microsoft/Iris/Debug/Data/InterpreterEntry.cs +++ b/UIX/Microsoft/Iris/Debug/Data/InterpreterEntry.cs @@ -1,11 +1,15 @@ -using System; +using Microsoft.Iris.Markup; +using System; using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; namespace Microsoft.Iris.Debug.Data; +[Serializable] public class InterpreterEntry { - public InterpreterEntry(object opCode, params OpCodeArgument[] args) + public InterpreterEntry(OpCode opCode, params OpCodeArgument[] args) { OpCode = opCode; @@ -15,22 +19,25 @@ public class InterpreterEntry Arguments = new List(); } - public object OpCode { get; } + public OpCode OpCode { get; } public IList Arguments { get; } public IList ReturnValues { get; } = new List(); public override string ToString() { - return $"{OpCode}({string.Join(", ", Arguments)}) -> [{ReturnValues}]"; + return $"{OpCode}({string.Join(", ", Arguments)}) -> [{string.Join(", ", ReturnValues)}]"; } } -public class OpCodeArgument +[Serializable] +public class OpCodeArgument : ISerializable { public string Name { get; set; } public Type Type { get; set; } public object Value { get; set; } + protected bool CanSerializeValue => Value is ISerializable; + public OpCodeArgument(string name, Type type, object value) { Name = name; @@ -38,5 +45,23 @@ public class OpCodeArgument Value = value; } + protected OpCodeArgument(SerializationInfo info, StreamingContext context) + { + Name = info.GetString(nameof(Name)); + Type = Type.GetType(info.GetString(nameof(Type)), false); + + bool canSerializeValue = info.GetBoolean(nameof(CanSerializeValue)); + Type valueSerializeType = canSerializeValue ? Type : typeof(string); + Value = info.GetValue(nameof(Value), valueSerializeType); + } + public override string ToString() => $"{Type} {Value}"; + + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue(nameof(Name), Name); + info.AddValue(nameof(Type), Type.FullName); + info.AddValue(nameof(CanSerializeValue), CanSerializeValue); + info.AddValue(nameof(Value), CanSerializeValue ? Value : Value.ToString()); + } } diff --git a/UIX/Microsoft/Iris/Debug/ZmqDebuggerClient.cs b/UIX/Microsoft/Iris/Debug/ZmqDebuggerClient.cs index 03b110b..c75a462 100644 --- a/UIX/Microsoft/Iris/Debug/ZmqDebuggerClient.cs +++ b/UIX/Microsoft/Iris/Debug/ZmqDebuggerClient.cs @@ -2,6 +2,8 @@ using NetMQ; using NetMQ.Sockets; using System; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; using System.Text; namespace Microsoft.Iris.Debug; @@ -34,8 +36,11 @@ public class ZmqDebuggerClient : IDebuggerClient, IDisposable switch (type) { case DebuggerMessageType.InterpreterOpCode: - string entry = Encoding.Unicode.GetString(bytes); - InterpreterStep?.Invoke(this, null); + { + using MemoryStream stream = new(bytes); + var entry = (InterpreterEntry)new BinaryFormatter().Deserialize(stream); + InterpreterStep?.Invoke(this, entry); + } break; case DebuggerMessageType.DispatcherStep: @@ -46,7 +51,7 @@ public class ZmqDebuggerClient : IDebuggerClient, IDisposable } } - private DebuggerMessageType RecieveDebuggerMessage(SubscriberSocket socket, out byte[] bytes) + private static DebuggerMessageType RecieveDebuggerMessage(SubscriberSocket socket, out byte[] bytes) { var frames = socket.ReceiveMultipartBytes(2); diff --git a/UIX/Microsoft/Iris/Debug/ZmqDebuggerServer.cs b/UIX/Microsoft/Iris/Debug/ZmqDebuggerServer.cs index c7455e6..9d28c72 100644 --- a/UIX/Microsoft/Iris/Debug/ZmqDebuggerServer.cs +++ b/UIX/Microsoft/Iris/Debug/ZmqDebuggerServer.cs @@ -1,6 +1,8 @@ using NetMQ; using NetMQ.Sockets; using System; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; using System.Text; namespace Microsoft.Iris.Debug; @@ -22,7 +24,10 @@ internal class ZmqDebuggerServer : IDebuggerServer, IDisposable public void LogInterpreterOpCode(object context, Data.InterpreterEntry entry) { - SendDebuggerMessage(DebuggerMessageType.InterpreterOpCode, entry.ToString()); + using MemoryStream entryStream = new(); + new BinaryFormatter().Serialize(entryStream, entry); + + SendDebuggerMessage(DebuggerMessageType.InterpreterOpCode, entryStream.ToArray()); } public void LogDispatcher(string message) diff --git a/UIX/Microsoft/Iris/Markup/Interpreter.cs b/UIX/Microsoft/Iris/Markup/Interpreter.cs index db2cca2..e110a50 100644 --- a/UIX/Microsoft/Iris/Markup/Interpreter.cs +++ b/UIX/Microsoft/Iris/Markup/Interpreter.cs @@ -90,6 +90,10 @@ namespace Microsoft.Iris.Markup int num = reader.ReadUInt16(); TypeSchema typeSchema = importTables.TypeImports[num]; object obj = typeSchema.ConstructDefault(); + + entry.Arguments.Add(new Debug.Data.OpCodeArgument( + "type", typeof(TypeSchema), typeSchema)); + ReportErrorOnNull(obj, "Construction", typeSchema.Name); if (!ErrorsDetected(watermark, ref result, ref errorsDetected)) { @@ -210,7 +214,12 @@ namespace Microsoft.Iris.Markup int num8 = reader.ReadUInt16(); SymbolReference symbolRef = symbolReferenceTable[num8]; object obj8 = context.ReadSymbol(symbolRef); + + entry.Arguments.Add(new Debug.Data.OpCodeArgument( + "symbolRef", typeof(SymbolReference), symbolRef)); + stack.Push(obj8); + if (Trace.IsCategoryEnabled(TraceCategory.Markup)) { } @@ -222,7 +231,14 @@ namespace Microsoft.Iris.Markup object value = (opCode == OpCode.WriteSymbolPeek) ? stack.Peek() : stack.Pop(); int num9 = reader.ReadUInt16(); SymbolReference symbolRef2 = symbolReferenceTable[num9]; + + entry.Arguments.Add(new Debug.Data.OpCodeArgument( + "symbolRef", typeof(SymbolReference), symbolRef2)); + entry.Arguments.Add(new Debug.Data.OpCodeArgument( + "value", typeof(object), value)); + context.WriteSymbol(symbolRef2, value); + if (Trace.IsCategoryEnabled(TraceCategory.Markup)) { } diff --git a/UIX/Microsoft/Iris/Markup/OpCode.cs b/UIX/Microsoft/Iris/Markup/OpCode.cs index d8deb6f..5883f54 100644 --- a/UIX/Microsoft/Iris/Markup/OpCode.cs +++ b/UIX/Microsoft/Iris/Markup/OpCode.cs @@ -4,56 +4,58 @@ // MVID: A56C6C9D-B7F6-46A9-8BDE-B3D9B8D60B11 // Assembly location: C:\Program Files\Zune\UIX.dll -namespace Microsoft.Iris.Markup +using System; + +namespace Microsoft.Iris.Markup; + +[Serializable] +public enum OpCode : byte { - public enum OpCode : byte - { - ConstructObject = 1, - ConstructObjectIndirect = 2, - ConstructObjectParam = 3, - ConstructFromString = 4, - ConstructFromBinary = 5, - InitializeInstance = 6, - InitializeInstanceIndirect = 7, - LookupSymbol = 8, - WriteSymbol = 9, - WriteSymbolPeek = 10, // 0x0A - ClearSymbol = 11, // 0x0B - PropertyInitialize = 12, // 0x0C - PropertyInitializeIndirect = 13, // 0x0D - PropertyListAdd = 14, // 0x0E - PropertyDictionaryAdd = 15, // 0x0F - PropertyAssign = 16, // 0x10 - PropertyAssignStatic = 17, // 0x11 - PropertyGet = 18, // 0x12 - PropertyGetPeek = 19, // 0x13 - PropertyGetStatic = 20, // 0x14 - MethodInvoke = 21, // 0x15 - MethodInvokePeek = 22, // 0x16 - MethodInvokeStatic = 23, // 0x17 - MethodInvokePushLastParam = 24, // 0x18 - MethodInvokeStaticPushLastParam = 25, // 0x19 - VerifyTypeCast = 26, // 0x1A - ConvertType = 27, // 0x1B - Operation = 28, // 0x1C - IsCheck = 29, // 0x1D - As = 30, // 0x1E - TypeOf = 31, // 0x1F - PushNull = 32, // 0x20 - PushConstant = 33, // 0x21 - PushThis = 34, // 0x22 - DiscardValue = 35, // 0x23 - ReturnValue = 36, // 0x24 - ReturnVoid = 37, // 0x25 - JumpIfFalse = 38, // 0x26 - JumpIfFalsePeek = 39, // 0x27 - JumpIfTruePeek = 40, // 0x28 - JumpIfDictionaryContains = 41, // 0x29 - JumpIfNullPeek = 42, // 0x2A - Jump = 43, // 0x2B - ConstructListenerStorage = 44, // 0x2C - Listen = 45, // 0x2D - DestructiveListen = 46, // 0x2E - EnterDebugState = 47, // 0x2F - } + ConstructObject = 1, + ConstructObjectIndirect = 2, + ConstructObjectParam = 3, + ConstructFromString = 4, + ConstructFromBinary = 5, + InitializeInstance = 6, + InitializeInstanceIndirect = 7, + LookupSymbol = 8, + WriteSymbol = 9, + WriteSymbolPeek = 10, // 0x0A + ClearSymbol = 11, // 0x0B + PropertyInitialize = 12, // 0x0C + PropertyInitializeIndirect = 13, // 0x0D + PropertyListAdd = 14, // 0x0E + PropertyDictionaryAdd = 15, // 0x0F + PropertyAssign = 16, // 0x10 + PropertyAssignStatic = 17, // 0x11 + PropertyGet = 18, // 0x12 + PropertyGetPeek = 19, // 0x13 + PropertyGetStatic = 20, // 0x14 + MethodInvoke = 21, // 0x15 + MethodInvokePeek = 22, // 0x16 + MethodInvokeStatic = 23, // 0x17 + MethodInvokePushLastParam = 24, // 0x18 + MethodInvokeStaticPushLastParam = 25, // 0x19 + VerifyTypeCast = 26, // 0x1A + ConvertType = 27, // 0x1B + Operation = 28, // 0x1C + IsCheck = 29, // 0x1D + As = 30, // 0x1E + TypeOf = 31, // 0x1F + PushNull = 32, // 0x20 + PushConstant = 33, // 0x21 + PushThis = 34, // 0x22 + DiscardValue = 35, // 0x23 + ReturnValue = 36, // 0x24 + ReturnVoid = 37, // 0x25 + JumpIfFalse = 38, // 0x26 + JumpIfFalsePeek = 39, // 0x27 + JumpIfTruePeek = 40, // 0x28 + JumpIfDictionaryContains = 41, // 0x29 + JumpIfNullPeek = 42, // 0x2A + Jump = 43, // 0x2B + ConstructListenerStorage = 44, // 0x2C + Listen = 45, // 0x2D + DestructiveListen = 46, // 0x2E + EnterDebugState = 47, // 0x2F }