public CorValue TypeMemberExpressionInvoke(ExpressionParsingResult info) { var inspector = CreateInspector(); foreach (CorValue arg in info.Arguments) { inspector.AddArg(arg); } CorValue result; if (info.IsSetter) { if (info.Instance != null) { result = inspector.Set(info.Member, info.Instance); } else { result = inspector.Set(info.Member); } } else { if (info.Instance != null) { result = inspector.Invoke(info.Member, info.Instance); } else { result = inspector.Invoke(info.Member); } } return(result); }
public CorValue VariableExpressionInvoke(ExpressionParsingResult info) { //based on MdbgCommands.SetCmd(string arguments) if (info.Instance == null) { throw new Exception("Cannot resolve variable "); } if (info.Arguments == null || !info.Arguments.Any()) { throw new Exception("Cannot resolve arguments "); } // Arguments has to be in the form of variable=varName, variable=value or variable=(<type>)value, // where we use the ldasm naming convention (e.g. "int", "sbyte", "ushort", etc...) for <type>. // Example inputs: var=myInt, var=45, var=(long)45 MDbgValue lsMVar = new MDbgValue(process, info.Instance); CorValue val = info.Arguments.First(); CorGenericValue valGeneric = val as CorGenericValue; bool bIsReferenceValue = val is CorReferenceValue; if (lsMVar != null) { if (valGeneric != null) { CorValue lsVar = lsMVar.CorValue; if (lsVar == null) { throw new Exception("cannot set constant values to unavailable variables"); } // val is a primitive value CorGenericValue lsGenVal = lsVar.CastToGenericValue(); if (lsGenVal == null) { throw new Exception("cannot set constant values to non-primitive values"); } try { // We want to allow some type coercion. Eg, casting between integer precisions. lsMVar.Value = val; // This may do type coercion } catch (MDbgValueWrongTypeException) { throw new Exception(String.Format("Type mismatch. Can't convert from {0} to {1}", val.Type, lsGenVal.Type)); } } else if (bIsReferenceValue) { //reget variable lsMVar = process.ResolveVariable(info.Member, process.Threads.Active.CurrentFrame); lsMVar.Value = val; } else { if (val.CastToHeapValue() != null) { throw new Exception("Heap values should be assigned only to debugger variables"); } if (val.CastToGenericValue() != null) { lsMVar.Value = val.CastToGenericValue(); } else { lsMVar.Value = val.CastToReferenceValue(); } } } // as a last thing we do is to return new value of the variable lsMVar = process.ResolveVariable(info.Member, process.Threads.Active.CurrentFrame); return(lsMVar.CorValue); }
public ExpressionParsingResult ParseExpression(string expression) { //the expression is either setter of method invoke var result = new ExpressionParsingResult(); result.IsSetter = expression.IsSetExpression(); result.Expression = expression; int bracketIndex = expression.IndexOfAny(new[] { '(', '=' }); string methodName = expression.Substring(0, bracketIndex).Trim(); string args = expression.Substring(bracketIndex).Replace("(", "").Replace(")", "").Replace("=", "").Trim(); string[] methodParts = methodName.Split('.'); if (methodParts.Length == 1 && result.IsSetter) //myVar=3 { result.IsLocalVariable = true; } result.ExpressionValue = args; string reference; if (methodParts.Length == 1) { //varName reference = methodParts[0]; } else { //<<TypeName>|<CodeReference>>.<MethodName> reference = string.Join(".", methodParts.Take(methodParts.Length - 1).ToArray()); } try { if ((expression.IsInvokeExpression() || expression.IsSetExpression()) && methodParts.Length == 1) { MDbgValue callingObject = process.ResolveVariable("this", process.Threads.Active.CurrentFrame); var mName = methodParts[0]; //either instance or static (e.g. "do()") MDbgFunction func = process.ResolveFunctionNameFromScope(mName); if (func != null) //method call { result.IsLocalVariable = false; if (func.MethodInfo.IsStatic) //static method call { result.Instance = null; result.Member = process.Threads.Active.CurrentFrame.Function.MethodInfo.DeclaringType.FullName + "." + mName; } else { result.Instance = callingObject.CorValue; result.Member = mName; } } else //variable assignment { var variable = process.ResolveVariable(reference, process.Threads.Active.CurrentFrame); if (variable != null)//local variable assignment { result.IsLocalVariable = true; result.Instance = variable.CorValue; result.Member = reference; } else { if (callingObject == null) //static member assignment { result.IsLocalVariable = false; result.Instance = null; result.Member = process.Threads.Active.CurrentFrame.Function.MethodInfo.DeclaringType.FullName + "." + mName; } else //instance member assignment { result.IsLocalVariable = false; result.Instance = callingObject.CorValue; result.Member = methodParts.Last(); } } } } else { var instance = process.ResolveVariable(reference, process.Threads.Active.CurrentFrame); if (instance != null) { result.Instance = instance.CorValue; result.Member = methodParts.Last(); } } } catch { } if (result.Instance == null && result.Member == null) { result.Member = methodName; } CorEval eval = process.Threads.Active.CorThread.CreateEval(); // Get Variables ArrayList vars = new ArrayList(); String arg; if (args.Length != 0) { foreach (var item in args.Split(',')) { arg = item.Trim(); CorValue v = process.m_engine.ParseExpression(arg, process, process.Threads.Active.CurrentFrame); if (v == null) { throw new Exception("Cannot resolve expression or variable " + arg); } if (v is CorGenericValue) { vars.Add(v as CorValue); } else { CorHeapValue hv = v.CastToHeapValue(); if (hv != null) { // we cannot pass directly heap values, we need to pass reference to heap valus CorReferenceValue myref = eval.CreateValue(CorElementType.ELEMENT_TYPE_CLASS, null).CastToReferenceValue(); myref.Value = hv.Address; vars.Add(myref); } else { vars.Add(v); } } } } result.Arguments = (CorValue[])vars.ToArray(typeof(CorValue)); return(result); }