From: Jeffrey Stedfast Date: Tue, 10 Jun 2014 19:15:56 +0000 (-0400) Subject: [Mono.Debugger.Soft] Improved ILInterpreter to eval properties that return a primitiv... X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=db0132029e8d0f34cc7412476f1568b667725a0c;p=mono.git [Mono.Debugger.Soft] Improved ILInterpreter to eval properties that return a primitive constant --- diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInterpreter.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInterpreter.cs index e0175f36bdf..d004991988b 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInterpreter.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInterpreter.cs @@ -23,8 +23,13 @@ namespace Mono.Debugger.Soft // IL_0008: br IL_000d // IL_000d: ldloc.0 // IL_000e: ret + // ... or returns a simple constant: + // IL_0000: ldc.i4 1024 + // IL_0005: conv.i8 + // IL_0006: ret if (args != null && args.Length != 0) - throw new NotSupportedException (); + throw new NotSupportedException (); + if (method.IsStatic || method.DeclaringType.IsValueType || this_val == null || !(this_val is ObjectMirror)) throw new NotSupportedException (); @@ -32,58 +37,333 @@ namespace Mono.Debugger.Soft if (instructions.Count > 16) throw new NotSupportedException (); - Value[] stack = new Value [16]; + var stack = new Value [16]; + var ins = instructions [0]; Value locals_0 = null; - Value res = null; - - int sp = 0; int ins_count = 0; - var ins = instructions [0]; + int sp = 0; + while (ins != null) { if (ins_count > 16) throw new NotImplementedException (); - ins_count ++; + var next = ins.Next; + ins_count++; var op = ins.OpCode; if (op == OpCodes.Nop) { } else if (op == OpCodes.Ldarg_0) { - if (sp > 0) + if (sp != 0) throw new NotSupportedException (); + stack [sp++] = this_val; } else if (op == OpCodes.Ldfld) { if (sp != 1) throw new NotSupportedException (); - var obj = (ObjectMirror)stack [--sp]; - var field = (FieldInfoMirror)ins.Operand; + + var obj = (ObjectMirror) stack [--sp]; + var field = (FieldInfoMirror) ins.Operand; try { stack [sp++] = obj.GetValue (field); } catch (ArgumentException) { throw new NotSupportedException (); } + } else if (op == OpCodes.Ldc_I4_0) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 0); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_1) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 1); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_2) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 2); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_3) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 3); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_4) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 4); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_5) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 5); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_6) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 6); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_7) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 7); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_8) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 8); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_M1) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, -1); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_S) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I8) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_R4) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_R8) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_I) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToInt32 (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_I1) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToSByte (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_U1) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToByte (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_I2) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToInt16 (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_U2) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt16 (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_I4) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToInt32 (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_U4) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt32 (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_I8) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToInt64 (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_U8) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt64 (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_R4) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToSingle (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_R8) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToDouble (primitive.Value)); + } catch { + throw new NotSupportedException (); + } } else if (op == OpCodes.Stloc_0) { if (sp != 1) throw new NotSupportedException (); + locals_0 = stack [--sp]; } else if (op == OpCodes.Br) { - next = (ILInstruction)ins.Operand; + next = (ILInstruction) ins.Operand; } else if (op == OpCodes.Ldloc_0) { if (sp != 0) throw new NotSupportedException (); + stack [sp++] = locals_0; } else if (op == OpCodes.Ret) { - if (sp == 0) - res = null; - else - res = stack [--sp]; - break; + if (sp > 0) { + var res = stack [--sp]; + + var primitive = res as PrimitiveValue; + if (method.ReturnType.IsPrimitive && primitive != null) { + // cast the primitive value to the return type + try { + switch (method.ReturnType.CSharpName) { + case "double": res = new PrimitiveValue (method.VirtualMachine, Convert.ToDouble (primitive.Value)); break; + case "float": res = new PrimitiveValue (method.VirtualMachine, Convert.ToSingle (primitive.Value)); break; + case "ulong": res = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt64 (primitive.Value)); break; + case "long": res = new PrimitiveValue (method.VirtualMachine, Convert.ToInt64 (primitive.Value)); break; + case "uint": res = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt32 (primitive.Value)); break; + case "int": res = new PrimitiveValue (method.VirtualMachine, Convert.ToInt32 (primitive.Value)); break; + case "ushort": res = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt16 (primitive.Value)); break; + case "short": res = new PrimitiveValue (method.VirtualMachine, Convert.ToInt16 (primitive.Value)); break; + case "sbyte": res = new PrimitiveValue (method.VirtualMachine, Convert.ToSByte (primitive.Value)); break; + case "byte": res = new PrimitiveValue (method.VirtualMachine, Convert.ToByte (primitive.Value)); break; + case "char": res = new PrimitiveValue (method.VirtualMachine, Convert.ToChar (primitive.Value)); break; + case "bool": res = new PrimitiveValue (method.VirtualMachine, Convert.ToBoolean (primitive.Value)); break; + } + } catch { + throw new NotSupportedException (); + } + } + + return res; + } + + return null; } else { throw new NotSupportedException (); } + ins = next; } - return res; + return null; } } }