예제 #1
0
        static TargetObject ImplicitReferenceConversion(MdbEvaluationContext ctx,
                                                        TargetClassObject obj,
                                                        TargetClassType type)
        {
            if (obj.Type == type)
            {
                return(obj);
            }

            if (obj.Type.HasParent)
            {
                TargetObject pobj = obj.GetParentObject(ctx.Thread);
                if (pobj != null)
                {
                    pobj = ImplicitConversion(ctx, pobj, type);
                    if (pobj != null)
                    {
                        return(pobj);
                    }
                }
            }

            if (ImplicitReferenceConversionExists(ctx, obj.Type, type))
            {
                return(obj);
            }
            return(null);
        }
예제 #2
0
        public static TargetObject ImplicitConversion(MdbEvaluationContext ctx,
                                                      TargetObject obj, TargetType type)
        {
            if (obj.Type.Equals(type))
            {
                return(obj);
            }

            if (type is TargetObjectType || ObjectUtil.FixTypeName(type.Name) == "System.Object")
            {
                if (obj.Type.IsByRef)
                {
                    return(obj);
                }
                return(BoxValue(ctx, obj));
            }

            if (obj is TargetEnumObject && type is TargetFundamentalType)
            {
                TargetEnumObject e = (TargetEnumObject)obj;
                return(ImplicitConversion(ctx, e.GetValue(ctx.Thread), type));
            }

            if (type is TargetEnumType)
            {
                TargetEnumType e = (TargetEnumType)type;
                return(ImplicitConversion(ctx, obj, e.Value.Type));
            }

            if (obj is TargetArrayObject && type.Name == "System.Array")
            {
                return(obj);
            }

            if (obj is TargetArrayObject && type is TargetArrayType)
            {
                TargetArrayObject sa = (TargetArrayObject)obj;
                TargetArrayType   ta = (TargetArrayType)type;
                if (sa.Type.ElementType.Equals(ta.ElementType))
                {
                    return(obj);
                }
            }

            if ((obj is TargetFundamentalObject) && (type is TargetFundamentalType))
            {
                return(ImplicitFundamentalConversion(
                           ctx, (TargetFundamentalObject)obj,
                           (TargetFundamentalType)type));
            }

            if ((obj is TargetClassObject) && (type is TargetClassType))
            {
                return(ImplicitReferenceConversion(
                           ctx, (TargetClassObject)obj,
                           (TargetClassType)type));
            }

            return(null);
        }
예제 #3
0
        static bool ImplicitReferenceConversionExists(MdbEvaluationContext ctx,
                                                      TargetStructType source,
                                                      TargetStructType target)
        {
            if (source == target)
            {
                return(true);
            }

            if (source.Module.Name.StartsWith("mscorlib,") && target.Module.Name.StartsWith("mscorlib,"))
            {
                Type t1 = Type.GetType(source.Name);
                Type t2 = Type.GetType(target.Name);
                return(t2.IsAssignableFrom(t1));
            }

            if (!source.HasParent)
            {
                return(false);
            }

            TargetStructType parent_type = source.GetParentType(ctx.Thread);

            return(ImplicitReferenceConversionExists(ctx, parent_type, target));
        }
예제 #4
0
        public static TargetObject ExplicitFundamentalConversion(MdbEvaluationContext ctx,
                                                                 TargetFundamentalObject obj,
                                                                 TargetFundamentalType type)
        {
            TargetObject retval = ImplicitFundamentalConversion(ctx, obj, type);

            if (retval != null)
            {
                return(retval);
            }

            FundamentalKind tkind = type.FundamentalKind;

            try {
                object value     = obj.GetObject(ctx.Thread);
                object new_value = ImplicitFundamentalConversion(value, tkind);
                if (new_value == null)
                {
                    return(null);
                }

                return(type.Language.CreateInstance(ctx.Thread, new_value));
            } catch {
                return(null);
            }
        }
예제 #5
0
        public static TargetStructObject ToStructObject(MdbEvaluationContext ctx, TargetObject obj)
        {
            TargetStructObject sobj = obj as TargetStructObject;

            if (sobj != null)
            {
                return(sobj);
            }

            TargetObjectObject oobj = obj as TargetObjectObject;

            if (oobj != null)
            {
                return(oobj.GetClassObject(ctx.Thread));
            }

            TargetArrayObject aobj = obj as TargetArrayObject;

            if ((aobj != null) && aobj.HasClassObject)
            {
                return(aobj.GetClassObject(ctx.Thread));
            }

            return(null);
        }
		public static ValueReference CreateIndexerValueReference (MdbEvaluationContext ctx, TargetObject target, TargetObject[] index)
		{
			TargetFundamentalObject mstr = target as TargetFundamentalObject;
			if (mstr != null && mstr.TypeName == "string") {
				// Special case for strings
				string name = "[" + ctx.Evaluator.TargetObjectToExpression (ctx, index[0]) + "]";
				string val = (string) mstr.GetObject (ctx.Thread);
				object oo = ctx.Adapter.TargetObjectToObject (ctx, index[0]);
				int idx = (int) Convert.ChangeType (oo, typeof(int));
				return LiteralValueReference.CreateObjectLiteral (ctx, name, val [idx]);
			}
			
			TargetStructObject sob = target as TargetStructObject;
			if (sob == null)
				return null;
			
			TargetPropertyInfo indexerProp = null;
			foreach (MemberReference mem in ObjectUtil.GetTypeMembers (ctx, target.Type, false, true, true, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) {
				if (mem.Member.IsStatic)
					continue;
				if (mem.Member is TargetPropertyInfo) {
					TargetPropertyInfo prop = (TargetPropertyInfo) mem.Member;
					if (prop.CanRead && prop.Getter.ParameterTypes.Length == 1) {
						indexerProp = prop;
						break;
					}
				}
			}
			if (indexerProp != null)
				return new IndexerValueReference (ctx, sob, index, indexerProp);
			else
				return null;
		}
예제 #7
0
        public static bool ImplicitConversionExists(MdbEvaluationContext ctx,
                                                    TargetType source, TargetType target)
        {
            if (source.Equals(target))
            {
                return(true);
            }

            if (source is TargetArrayType && target.Name == "System.Array")
            {
                return(true);
            }

            if (ObjectUtil.FixTypeName(target.Name) == "System.Object")
            {
                return(true);
            }

            if (source is TargetArrayType && target is TargetArrayType)
            {
                TargetArrayType sa = (TargetArrayType)source;
                TargetArrayType ta = (TargetArrayType)target;
                return(sa.ElementType.Equals(ta.ElementType));
            }

            if (source is TargetEnumType)
            {
                TargetEnumType e = (TargetEnumType)source;
                if (ImplicitConversionExists(ctx, e.Value.Type, target))
                {
                    return(true);
                }
            }

            if (target is TargetEnumType)
            {
                TargetEnumType e = (TargetEnumType)target;
                if (ImplicitConversionExists(ctx, source, e.Value.Type))
                {
                    return(true);
                }
            }

            if ((source is TargetFundamentalType) && (target is TargetFundamentalType))
            {
                return(ImplicitFundamentalConversionExists(
                           (TargetFundamentalType)source,
                           (TargetFundamentalType)target));
            }

            if ((source is TargetClassType) && (target is TargetClassType))
            {
                return(ImplicitReferenceConversionExists(
                           ctx, (TargetClassType)source,
                           (TargetClassType)target));
            }

            return(false);
        }
예제 #8
0
        public override void CopyFrom(Mono.Debugging.Evaluation.EvaluationContext gctx)
        {
            base.CopyFrom(gctx);
            MdbEvaluationContext ctx = (MdbEvaluationContext)gctx;

            thread = ctx.thread;
            frame  = ctx.frame;
        }
예제 #9
0
        public ML.TargetObject RuntimeInvoke(MdbEvaluationContext ctx, ML.TargetFunctionType function,
                                             ML.TargetStructObject object_argument,
                                             params ML.TargetObject[] param_objects)
        {
            MethodCall mc = new MethodCall(ctx, function, object_argument, param_objects);

            ctx.Adapter.AsyncExecute(mc, ctx.Options.EvaluationTimeout);
            return(mc.ReturnValue);
        }
예제 #10
0
        static TargetStructObject TryCurrentCast(MdbEvaluationContext ctx, TargetClassObject source, TargetClassType target_type)
        {
            TargetStructObject current = source.GetCurrentObject(ctx.Thread);

            if (current == null)
            {
                return(null);
            }

            return(TryParentCast(ctx, current, current.Type, target_type));
        }
예제 #11
0
        public static TargetObject ImplicitConversionRequired(MdbEvaluationContext ctx,
                                                              TargetObject obj, TargetType type)
        {
            TargetObject new_obj = ImplicitConversion(ctx, obj, type);

            if (new_obj != null)
            {
                return(new_obj);
            }

            throw new Exception(string.Format("Cannot implicitly convert `{0}' to `{1}'", obj.Type.Name, type.Name));
        }
        public static ValueReference CreateIndexerValueReference(MdbEvaluationContext ctx, TargetObject target, TargetObject[] index)
        {
            TargetFundamentalObject mstr = target as TargetFundamentalObject;

            if (mstr != null && mstr.TypeName == "string")
            {
                // Special case for strings
                string name = "[" + ctx.Evaluator.TargetObjectToExpression(ctx, index[0]) + "]";
                string val  = (string)mstr.GetObject(ctx.Thread);
                object oo   = ctx.Adapter.TargetObjectToObject(ctx, index[0]);
                int    idx  = (int)Convert.ChangeType(oo, typeof(int));
                return(LiteralValueReference.CreateObjectLiteral(ctx, name, val [idx]));
            }

            TargetStructObject sob = target as TargetStructObject;

            if (sob == null)
            {
                return(null);
            }

            TargetPropertyInfo indexerProp = null;

            foreach (MemberReference mem in ObjectUtil.GetTypeMembers(ctx, target.Type, false, true, true, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
            {
                if (mem.Member.IsStatic)
                {
                    continue;
                }
                if (mem.Member is TargetPropertyInfo)
                {
                    TargetPropertyInfo prop = (TargetPropertyInfo)mem.Member;
                    if (prop.CanRead && prop.Getter.ParameterTypes.Length == 1)
                    {
                        indexerProp = prop;
                        break;
                    }
                }
            }
            if (indexerProp != null)
            {
                return(new IndexerValueReference(ctx, sob, index, indexerProp));
            }
            else
            {
                return(null);
            }
        }
예제 #13
0
        public static bool TryCast(MdbEvaluationContext ctx, TargetType source, TargetClassType target_type)
        {
            if (source == target_type)
            {
                return(true);
            }

            TargetClassType stype = ToClassType(source);

            if (stype == null)
            {
                return(false);
            }

            return(TryParentCast(ctx, stype, target_type));
        }
예제 #14
0
        static bool TryParentCast(MdbEvaluationContext ctx, TargetStructType source_type, TargetStructType target_type)
        {
            if (source_type == target_type)
            {
                return(true);
            }

            if (!source_type.HasParent)
            {
                return(false);
            }

            TargetStructType parent_type = source_type.GetParentType(ctx.Thread);

            return(TryParentCast(ctx, parent_type, target_type));
        }
예제 #15
0
        static TargetStructObject TryParentCast(MdbEvaluationContext ctx, TargetStructObject source, TargetStructType source_type, TargetStructType target_type)
        {
            if (source_type == target_type)
            {
                return(source);
            }

            if (!source_type.HasParent)
            {
                return(null);
            }

            TargetStructType parent_type = source_type.GetParentType(ctx.Thread);

            source = TryParentCast(ctx, source, parent_type, target_type);
            if (source == null)
            {
                return(null);
            }

            return(source.GetParentObject(ctx.Thread) as TargetClassObject);
        }
예제 #16
0
        static TargetObject ImplicitFundamentalConversion(MdbEvaluationContext ctx,
                                                          TargetFundamentalObject obj,
                                                          TargetFundamentalType type)
        {
            FundamentalKind skind = obj.Type.FundamentalKind;
            FundamentalKind tkind = type.FundamentalKind;

            if (!ImplicitFundamentalConversionExists(skind, tkind))
            {
                return(null);
            }

            object value = obj.GetObject(ctx.Thread);

            object new_value = ImplicitFundamentalConversion(value, tkind);

            if (new_value == null)
            {
                return(null);
            }

            return(type.Language.CreateInstance(ctx.Thread, new_value));
        }
예제 #17
0
        public static TargetObject TryCast(MdbEvaluationContext ctx, TargetObject source, TargetClassType target_type)
        {
            if (source.Type == target_type)
            {
                return(source);
            }

            TargetClassObject sobj = ToClassObject(ctx, source);

            if (sobj == null)
            {
                return(null);
            }

            TargetStructObject result = TryParentCast(ctx, sobj, sobj.Type, target_type);

            if (result != null)
            {
                return(result);
            }

            return(TryCurrentCast(ctx, sobj, target_type));
        }
		public static IEnumerable<MemberReference> GetTypeMembers (MdbEvaluationContext ctx, TargetType t, bool includeFields, bool includeProps, bool includeMethods, BindingFlags flags)
		{
			// Don't use yield in this method because the whole list of members
			// must be retrieved before we can do anything with them.
			List<MemberReference> members = new List<MemberReference> ();
			
			Dictionary<string,string> foundMethods = new Dictionary<string,string> ();

			while (t != null) {
				
				TargetFieldInfo[] fields = null;
				TargetPropertyInfo[] properties = null;
				TargetMethodInfo[] methods = null;

				TargetClass cls = t.HasClassType ? t.ClassType.GetClass (ctx.Thread) : null;
				if (cls != null) {
					if (includeFields)
						fields = cls.GetFields (ctx.Thread);
					if (includeProps)
						properties = cls.GetProperties (ctx.Thread);
					if (includeMethods)
						methods = cls.GetMethods (ctx.Thread);
				}
				else {
					TargetClassType ct = t as TargetClassType;
					if (ct == null && t.HasClassType)
						ct = t.ClassType;
					if (ct != null) {
						if (includeFields)
							fields = ct.Fields;
						if (includeProps)
							properties = ct.Properties;
						if (includeMethods)
							methods = ct.Methods;
					}
				}
				
				if (fields != null) {
					foreach (TargetFieldInfo field in fields) {
						if (field.IsCompilerGenerated)
							continue;
						if (field.Accessibility == TargetMemberAccessibility.Public && (flags & BindingFlags.Public) == 0)
							continue;
						if (field.Accessibility != TargetMemberAccessibility.Public && (flags & BindingFlags.NonPublic) == 0)
							continue;
						if (field.IsStatic && (flags & BindingFlags.Static) == 0)
							continue;
						if (!field.IsStatic && (flags & BindingFlags.Instance) == 0)
							continue;
						members.Add (new MemberReference (field, t));
					}
				}
				
				if (properties != null) {
					foreach (TargetPropertyInfo prop in properties) {
						if (prop.Accessibility == TargetMemberAccessibility.Public && (flags & BindingFlags.Public) == 0)
							continue;
						if (prop.Accessibility != TargetMemberAccessibility.Public && (flags & BindingFlags.NonPublic) == 0)
							continue;
						if (prop.IsStatic && (flags & BindingFlags.Static) == 0)
							continue;
						if (!prop.IsStatic && (flags & BindingFlags.Instance) == 0)
							continue;
						members.Add (new MemberReference (prop, t));
					}
				}
				
				if (methods != null) {
					foreach (TargetMethodInfo met in methods) {
						if (met.Accessibility == TargetMemberAccessibility.Public && (flags & BindingFlags.Public) == 0)
							continue;
						if (met.Accessibility != TargetMemberAccessibility.Public && (flags & BindingFlags.NonPublic) == 0)
							continue;
						if (met.IsStatic && (flags & BindingFlags.Static) == 0)
							continue;
						if (!met.IsStatic && (flags & BindingFlags.Instance) == 0)
							continue;
						string sig = met.FullName;
						if (!foundMethods.ContainsKey (sig)) {
							foundMethods [sig] = sig;
							members.Add (new MemberReference (met, t));
						}
					}
				}
				
				TargetStructType type = t as TargetStructType;
				if (type != null && type.HasParent && (flags & BindingFlags.DeclaredOnly) == 0)
					t = type.GetParentType (ctx.Thread);
				else
					break;
			}
			return members;
		}
		static MemberReference OverloadResolve (MdbEvaluationContext ctx, string methodName, TargetType[] argtypes, List<MemberReference> candidates, bool throwIfNotFound)
		{
			// Ok, no we need to find an exact match.
			MemberReference match = null;
			int bestCount = -1;
			bool repeatedBestCount = false;
			
			foreach (MemberReference method in candidates) {
				string error;
				int matchCount;
				TargetFunctionType func;
				if (method.Member is TargetMethodInfo)
					func = (TargetFunctionType) ((TargetMethodInfo) method.Member).Type;
				else
					func = (TargetFunctionType) ((TargetPropertyInfo) method.Member).Getter;
				
				if (!IsApplicable (ctx, func, argtypes, out error, out matchCount))
					continue;

				if (matchCount == bestCount) {
					repeatedBestCount = true;
				} else if (matchCount > bestCount) {
					match = method;
					bestCount = matchCount;
					repeatedBestCount = false;
				}
			}
			
			if (match == null) {
				if (!throwIfNotFound)
					return null;
				if (methodName != null)
					throw new EvaluatorException ("Invalid arguments for method `{0}'.", methodName);
				else
					throw new EvaluatorException ("Invalid arguments for indexer.");
			}
			
			if (repeatedBestCount) {
				// If there is an ambiguous match, just pick the first match. If the user was expecting
				// something else, he can provide more specific arguments
				
/*				if (!throwIfNotFound)
					return null;
				if (methodName != null)
					throw new EvaluatorException ("Ambiguous method `{0}'; need to use full name", methodName);
				else
					throw new EvaluatorException ("Ambiguous arguments for indexer.", methodName);
*/			}
			 
			return match;
		}		
예제 #20
0
        public static TargetObject Cast(MdbEvaluationContext ctx, TargetObject obj, TargetType targetType)
        {
            obj = ObjectUtil.GetRealObject(ctx, obj);

            if (obj.Type == targetType)
            {
                return(obj);
            }

            if (targetType is TargetObjectType || ObjectUtil.FixTypeName(targetType.Name) == "System.Object")
            {
                if (obj.Type.IsByRef)
                {
                    return(obj);
                }
                return(BoxValue(ctx, obj));
            }

            if (targetType is TargetPointerType)
            {
                throw new NotSupportedException();
            }

            if (targetType is TargetFundamentalType)
            {
                TargetFundamentalObject fobj = obj as TargetFundamentalObject;
                if (fobj == null)
                {
                    throw new NotSupportedException();
                }

                TargetFundamentalType ftype = targetType as TargetFundamentalType;
                TargetObject          ob    = ExplicitFundamentalConversion(ctx, fobj, ftype);
                if (ob == null)
                {
                    throw new NotSupportedException();
                }
                return(ob);
            }

            if (targetType is TargetNullableType)
            {
                TargetNullableType ntype = (TargetNullableType)targetType;
                if (obj.Kind == TargetObjectKind.Null)
                {
                    return(obj);
                }
                else if (obj.Kind != TargetObjectKind.Nullable)
                {
                    return(ImplicitConversion(ctx, obj, ntype.ElementType));
                }

                TargetNullableType ntype2 = (TargetNullableType)obj.Type;
                if (ImplicitConversionExists(ctx, ntype2.ElementType, ntype.ElementType))
                {
                    return(obj);
                }
            }

            TargetClassType   ctype  = ToClassType(targetType);
            TargetClassObject source = ToClassObject(ctx, obj);

            if (source == null)
            {
                throw new Exception(string.Format("Variable is not a class type."));
            }

            return(TryCast(ctx, source, ctype));
        }
예제 #21
0
 static TargetObject BoxValue(MdbEvaluationContext ctx, TargetObject fobj)
 {
     return(ctx.Frame.Language.CreateBoxedObject(ctx.Thread, fobj));
 }
예제 #22
0
        public int InsertBreakEvent(DL.BreakEvent be, bool enable)
        {
            CancelRuntimeInvokes();
            DL.Breakpoint bp = be as DL.Breakpoint;
            MD.Event      ev = null;

            if (bp != null)
            {
                MD.SourceLocation   location = new MD.SourceLocation(bp.FileName, bp.Line);
                MD.SourceBreakpoint sbp      = new MD.SourceBreakpoint(session, ThreadGroup.Global, location);
                mdbAdaptor.InitializeBreakpoint(sbp);
                session.AddEvent(sbp);
                ev = sbp;
            }
            else if (be is Catchpoint)
            {
                lock (pendingCatchpoints) {
                    Catchpoint    cp  = (Catchpoint)be;
                    ML.TargetType exc = null;
                    if (process != null)
                    {
                        foreach (Module mod in process.Modules)
                        {
                            exc = mod.Language.LookupType(cp.ExceptionName);
                            if (exc != null)
                            {
                                break;
                            }
                        }
                    }
                    if (exc != null)
                    {
                        ev = session.InsertExceptionCatchPoint(process.MainThread, ThreadGroup.Global, exc);
                    }
                    else
                    {
                        pendingCatchpoints.Add(cp);
                        return(-1);
                    }
                }
            }

            ev.IsEnabled = enable;

            if (!initializing)
            {
                lock (debugger) {
                    mdbAdaptor.ActivateEvent(ev);
                }
            }

            if (bp != null && !running && !initializing && activeThread.CurrentFrame != null && !string.IsNullOrEmpty(bp.ConditionExpression) && bp.BreakIfConditionChanges)
            {
                // Initial expression evaluation
                MdbEvaluationContext ctx = new MdbEvaluationContext(activeThread, activeThread.CurrentFrame, null, SessionOptions.EvaluationOptions);
                ML.TargetObject      ob  = EvaluateExp(ctx, bp.ConditionExpression);
                if (ob != null)
                {
                    lastConditionValue [ev.Index] = evaluator.TargetObjectToExpression(ctx, ob).Value;
                }
            }

            events [ev.Index] = be;
            return(ev.Index);
        }
		static bool TryParentCast (MdbEvaluationContext ctx, TargetStructType source_type, TargetStructType target_type)
		{
			if (source_type == target_type)
				return true;

			if (!source_type.HasParent)
				return false;

			TargetStructType parent_type = source_type.GetParentType (ctx.Thread);
			return TryParentCast (ctx, parent_type, target_type);
		}
		static TargetStructObject TryCurrentCast (MdbEvaluationContext ctx, TargetClassObject source, TargetClassType target_type)
		{
			TargetStructObject current = source.GetCurrentObject (ctx.Thread);
			if (current == null)
				return null;

			return TryParentCast (ctx, current, current.Type, target_type);
		}
		static TargetObject BoxValue (MdbEvaluationContext ctx, TargetObject fobj)
		{
			return ctx.Frame.Language.CreateBoxedObject (ctx.Thread, fobj);
		}
		public static TargetObject Cast (MdbEvaluationContext ctx, TargetObject obj, TargetType targetType)
		{
			obj = ObjectUtil.GetRealObject (ctx, obj);
			
			if (obj.Type == targetType)
				return obj;
			
			if (targetType is TargetObjectType || ObjectUtil.FixTypeName (targetType.Name) == "System.Object") {
				if (obj.Type.IsByRef)
					return obj;
				return BoxValue (ctx, obj);
			}
			
			if (targetType is TargetPointerType)
				throw new NotSupportedException ();

			if (targetType is TargetFundamentalType) {
				TargetFundamentalObject fobj = obj as TargetFundamentalObject;
				if (fobj == null)
					throw new NotSupportedException ();

				TargetFundamentalType ftype = targetType as TargetFundamentalType;
				TargetObject ob = ExplicitFundamentalConversion (ctx, fobj, ftype);
				if (ob == null)
					throw new NotSupportedException ();
				return ob;
			}
			
			if (targetType is TargetNullableType) {
				TargetNullableType ntype = (TargetNullableType) targetType;
				if (obj.Kind == TargetObjectKind.Null)
					return obj;
				else if (obj.Kind != TargetObjectKind.Nullable)
					return ImplicitConversion (ctx, obj, ntype.ElementType);

				TargetNullableType ntype2 = (TargetNullableType) obj.Type;
				if (ImplicitConversionExists (ctx, ntype2.ElementType, ntype.ElementType))
					return obj;
			}

			TargetClassType ctype = ToClassType (targetType);
			TargetClassObject source = ToClassObject (ctx, obj);

			if (source == null)
				throw new Exception (string.Format ("Variable is not a class type."));

			return TryCast (ctx, source, ctype);
		}
		public ArrayAdaptor (MdbEvaluationContext ctx, TargetArrayObject array)
		{
			this.ctx = ctx;
			this.array = array;
		}
		static TargetStructObject TryParentCast (MdbEvaluationContext ctx, TargetStructObject source, TargetStructType source_type, TargetStructType target_type)
		{
			if (source_type == target_type)
				return source;

			if (!source_type.HasParent)
				return null;

			TargetStructType parent_type = source_type.GetParentType (ctx.Thread);
			source = TryParentCast (ctx, source, parent_type, target_type);
			if (source == null)
				return null;

			return source.GetParentObject (ctx.Thread) as TargetClassObject;
		}
		public TargetObject GetValue (MdbEvaluationContext ctx, TargetStructObject thisObj)
		{
			if (Member is TargetPropertyInfo) {
				TargetPropertyInfo prop = (TargetPropertyInfo) Member;
				return ObjectUtil.GetRealObject (ctx, Server.Instance.RuntimeInvoke (ctx, prop.Getter, thisObj));
			}
			else if (Member is TargetFieldInfo) {
				TargetFieldInfo field = (TargetFieldInfo) Member;
				if (field.HasConstValue)
					return ctx.Frame.Language.CreateInstance (ctx.Thread, field.ConstValue);
				TargetClass cls = DeclaringType.ClassType.GetClass (ctx.Thread);
				return ObjectUtil.GetRealObject (ctx, cls.GetField (ctx.Thread, thisObj, field));
			}
			else {
				TargetMethodInfo met = (TargetMethodInfo) Member;
				return ObjectUtil.GetRealObject (ctx, Server.Instance.RuntimeInvoke (ctx, met.Type, thisObj));
			}
		}
		public static TargetObject TryCast (MdbEvaluationContext ctx, TargetObject source, TargetClassType target_type)
		{
			if (source.Type == target_type)
				return source;

			TargetClassObject sobj = ToClassObject (ctx, source);
			if (sobj == null)
				return null;

			TargetStructObject result = TryParentCast (ctx, sobj, sobj.Type, target_type);
			if (result != null)
				return result;

			return TryCurrentCast (ctx, sobj, target_type);
		}
		object FindType (MdbEvaluationContext ctx, string typeName)
		{
			foreach (object typeDefinition in GetAllTypeDefinitions (ctx, true)) {
				string fullName = (string) GetProp (typeDefinition, "FullName");
				if (fullName == typeName)
					return typeDefinition;
			}
			return null;
		}
		public static bool TryCast (MdbEvaluationContext ctx, TargetType source, TargetClassType target_type)
		{
			if (source == target_type)
				return true;

			TargetClassType stype = ToClassType (source);
			if (stype == null)
				return false;

			return TryParentCast (ctx, stype, target_type);
		}
		public static TargetStructObject GetTypeOf (MdbEvaluationContext ctx, string typeName)
		{
			ctx.AssertTargetInvokeAllowed ();
			TargetType tt = ctx.Frame.Language.LookupType ("System.Type");
			if (tt == null)
				return null;

			TargetObject tn = ctx.Frame.Language.CreateInstance (ctx.Thread, ObjectUtil.FixTypeName (typeName));
			TargetObject res = CallStaticMethod (ctx, "GetType", tt, tn);
			return (TargetStructObject) ctx.GetRealObject (res);
		}
예제 #34
0
        bool BreakEventCheck(MD.TargetEventArgs args)
        {
            MD.StackFrame frame = args.Frame;
            if (!(args.Data is int))
            {
                return(true);
            }

            int eventHandle = (int)args.Data;

            DL.BreakEvent be;
            if (!events.TryGetValue(eventHandle, out be))
            {
                return(true);
            }

            // Check hit count
            if (be.HitCount > 0)
            {
                be.HitCount--;
                DispatchEvent(delegate {
                    NotifyBreakEventUpdate(eventHandle, be.HitCount, null);
                });
                return(false);
            }

            MdbEvaluationContext ctx = new MdbEvaluationContext(frame.Thread, frame, null, SessionOptions.EvaluationOptions);

            DL.Breakpoint bp = be as DL.Breakpoint;
            if (bp != null && !string.IsNullOrEmpty(bp.ConditionExpression))
            {
                ML.TargetObject val = EvaluateExp(ctx, bp.ConditionExpression);
                if (val == null)
                {
                    return(false);
                }
                if (bp.BreakIfConditionChanges)
                {
                    string current = evaluator.TargetObjectToExpression(ctx, val).Value;
                    string last;
                    bool   found = lastConditionValue.TryGetValue(eventHandle, out last);
                    lastConditionValue [eventHandle] = current;
                    if (!found || last == current)
                    {
                        return(false);
                    }
                }
                else
                {
                    ML.TargetFundamentalObject fob = val as ML.TargetFundamentalObject;
                    if (fob == null)
                    {
                        return(false);
                    }
                    object ob = fob.GetObject(frame.Thread);
                    if (!(ob is bool) || !(bool)ob)
                    {
                        return(false);
                    }
                }
            }

            switch (be.HitAction)
            {
            case HitAction.Break:
                return(true);

            case HitAction.CustomAction:
                return(controller.OnCustomBreakpointAction(be.CustomActionId, eventHandle));

            case HitAction.PrintExpression:
                if (string.IsNullOrEmpty(be.TraceExpression) || frame == null)
                {
                    return(false);
                }
                ML.TargetObject val = EvaluateExp(ctx, be.TraceExpression);
                if (val != null)
                {
                    string str = evaluator.TargetObjectToString(ctx, val);
                    DispatchEvent(delegate {
                        NotifyBreakEventUpdate(eventHandle, -1, str);
                    });
                }
                return(false);
            }
            return(false);
        }
		public static TargetObject CallStaticMethod (MdbEvaluationContext ctx, string name,
							  string typeName,
							  params TargetObject[] args)
		{
			return CallStaticMethod (ctx, name, ctx.Frame.Language.LookupType (typeName), args);
		}
		static TargetObject ImplicitFundamentalConversion (MdbEvaluationContext ctx,
								   TargetFundamentalObject obj,
								   TargetFundamentalType type)
		{
			FundamentalKind skind = obj.Type.FundamentalKind;
			FundamentalKind tkind = type.FundamentalKind;

			if (!ImplicitFundamentalConversionExists (skind, tkind))
				return null;

			object value = obj.GetObject (ctx.Thread);

			object new_value = ImplicitFundamentalConversion (value, tkind);
			if (new_value == null)
				return null;

			return type.Language.CreateInstance (ctx.Thread, new_value);
		}
		public static MemberReference OverloadResolve (MdbEvaluationContext ctx, string methodName, TargetType type, TargetType[] argtypes, bool allowInstance, bool allowStatic, bool throwIfNotFound)
		{
			List<MemberReference> candidates = new List<MemberReference> ();

			if (methodName == ".ctor") {
				TargetClassType ct = type as TargetClassType;
				if (ct == null && type.HasClassType)
					ct = type.ClassType;
				
				foreach (TargetMethodInfo met in ct.Constructors) {
					if (met.Type.ParameterTypes.Length == argtypes.Length)
						candidates.Add (new MemberReference (met, type));
				}
			}
			else {
				foreach (MemberReference mem in ObjectUtil.GetTypeMembers (ctx, type, false, false, true, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) {
					TargetMethodInfo met = (TargetMethodInfo) mem.Member;
					if (met.Name == methodName && met.Type.ParameterTypes.Length == argtypes.Length && (met.IsStatic && allowStatic || !met.IsStatic && allowInstance))
						candidates.Add (mem);
				}
			}
			
			if (candidates.Count == 1) {
				TargetFunctionType func = (TargetFunctionType) ((TargetMethodInfo) candidates [0].Member).Type;
				string error;
				int matchCount;
				if (IsApplicable (ctx, func, argtypes, out error, out matchCount))
					return candidates [0];

				if (throwIfNotFound)
					throw new EvaluatorException ("Invalid arguments for method `{0}': {1}", methodName, error);
				else
					return null;
			}

			if (candidates.Count == 0) {
				if (throwIfNotFound)
					throw new EvaluatorException ("Method `{0}' not found in type `{1}'.", methodName, type.Name);
				else
					return null;
			}

			return OverloadResolve (ctx, methodName, argtypes, candidates, throwIfNotFound);
		}
		public MethodCall (MdbEvaluationContext ctx, TargetFunctionType function, TargetStructObject object_argument, TargetObject[] param_objects)
		{
			this.ctx = ctx;
			this.function = function;
			this.object_argument = object_argument;
			this.param_objects = param_objects;
		}
		public static TargetObject ExplicitFundamentalConversion (MdbEvaluationContext ctx,
									  TargetFundamentalObject obj,
									  TargetFundamentalType type)
		{
			TargetObject retval = ImplicitFundamentalConversion (ctx, obj, type);
			if (retval != null)
				return retval;

			FundamentalKind tkind = type.FundamentalKind;

			try {
				object value = obj.GetObject (ctx.Thread);
				object new_value = ImplicitFundamentalConversion (value, tkind);
				if (new_value == null)
					return null;

				return type.Language.CreateInstance (ctx.Thread, new_value);
			} catch {
				return null;
			}
		}
		public IEnumerable<object> GetAllTypeDefinitions (MdbEvaluationContext ctx, bool includePrivate)
		{
			HashSet<object> visited = new HashSet<object> ();
			object methodHandle = ctx.Frame.Method.MethodHandle;

			if (methodHandle != null && methodHandle.GetType ().FullName == "Mono.Cecil.MethodDefinition") {
				object declaringType = GetProp (methodHandle, "DeclaringType");
				object module = GetProp (declaringType, "Module");
				object assembly = GetProp (module, "Assembly");
				object resolver = GetProp (module, "AssemblyResolver");
				
				foreach (object typeDefinition in GetAllTypeDefinitions (includePrivate, resolver, visited, assembly))
					yield return typeDefinition;
			}
		}
		static bool ImplicitReferenceConversionExists (MdbEvaluationContext ctx,
							       TargetStructType source,
							       TargetStructType target)
		{
			if (source == target)
				return true;

			if (source.Module.Name.StartsWith ("mscorlib,") && target.Module.Name.StartsWith ("mscorlib,")) {
				Type t1 = Type.GetType (source.Name);
				Type t2 = Type.GetType (target.Name);
				return t2.IsAssignableFrom (t1);
			}
			
			if (!source.HasParent)
				return false;

			TargetStructType parent_type = source.GetParentType (ctx.Thread);
			return ImplicitReferenceConversionExists (ctx, parent_type, target);
		}
		public static TargetObject CallMethod (MdbEvaluationContext ctx, string name,
							  TargetObject target,
							  params TargetObject[] args)
		{
#if REFLECTION_INVOKE
			if (target is TargetGenericInstanceObject || !(target is TargetStructObject)) {
				// Calling methods on generic objects is suprisingly not supported
				// by the debugger. As a workaround we do the call using reflection.
				
				if (name != "ToString" || args.Length != 0) {
					GetTypeOf (ctx, "System.Convert");
					TargetType cc = ctx.Frame.Language.LookupType ("System.Convert");
					SR.BindingFlags sf = SR.BindingFlags.InvokeMethod | SR.BindingFlags.Static | SR.BindingFlags.FlattenHierarchy | SR.BindingFlags.Public | SR.BindingFlags.NonPublic;
					CallMethodWithReflection (ctx, sf, "ToString", cc, null, target);
				}

				SR.BindingFlags f = SR.BindingFlags.InvokeMethod | SR.BindingFlags.Instance | SR.BindingFlags.Public | SR.BindingFlags.NonPublic;
				return CallMethodWithReflection (ctx, f, name, target.Type, target, args);
			}
#endif
			ctx.AssertTargetInvokeAllowed ();
			
			TargetType[] types = new TargetType [args.Length];
			for (int n=0; n<types.Length; n++)
				types [n] = args [n].Type;
			
			TargetStructObject starget = (TargetStructObject) target;
			MemberReference mem = OverloadResolve (ctx, name, starget.Type, types, true, false, true);
			TargetFunctionType function = (TargetFunctionType) ((TargetMethodInfo) mem.Member).Type;
			
			while (starget.Type != mem.DeclaringType) {
				TargetStructObject par = starget.GetParentObject (ctx.Thread);
				if (par != null)
					starget = par;
				else
					break;
			}
			
			TargetMethodSignature sig = function.GetSignature (ctx.Thread);

			TargetObject[] objs = new TargetObject [args.Length];
			for (int i = 0; i < args.Length; i++) {
				objs [i] = TargetObjectConvert.ImplicitConversionRequired (
					ctx, args [i], sig.ParameterTypes [i]);
			}

			return Server.Instance.RuntimeInvoke (ctx, function, starget, objs);
		}
		static TargetObject ImplicitReferenceConversion (MdbEvaluationContext ctx,
								 TargetClassObject obj,
								 TargetClassType type)
		{
			if (obj.Type == type)
				return obj;

			if (obj.Type.HasParent) {
				TargetObject pobj = obj.GetParentObject (ctx.Thread);
				if (pobj != null) {
					pobj = ImplicitConversion (ctx, pobj, type);
					if (pobj != null)
						return pobj;
				}
			}
			
			if (ImplicitReferenceConversionExists (ctx, obj.Type, type))
				return obj;
			return null;
		}
		public static TargetObject CallStaticMethod (MdbEvaluationContext ctx, string name,
							  TargetType type,
							  params TargetObject[] args)
		{
#if REFLECTION_INVOKE
			if (type is TargetGenericInstanceType || !(type is TargetStructType)) {
				// Calling methods on generic objects is suprisingly not supported
				// by the debugger. As a workaround we do the call using reflection.
				
				SR.BindingFlags f = SR.BindingFlags.InvokeMethod | SR.BindingFlags.Static | SR.BindingFlags.Public | SR.BindingFlags.NonPublic;
				return CallMethodWithReflection (ctx, f, name, type, null, args);
			}
#endif			
			ctx.AssertTargetInvokeAllowed ();
			
			TargetType[] types = new TargetType [args.Length];
			for (int n=0; n<types.Length; n++)
				types [n] = args [n].Type;
			
			MemberReference mem = OverloadResolve (ctx, name, type, types, false, true, true);
			TargetFunctionType function = (TargetFunctionType) ((TargetMethodInfo) mem.Member).Type;
			
			TargetMethodSignature sig = function.GetSignature (ctx.Thread);

			TargetObject[] objs = new TargetObject [args.Length];
			for (int i = 0; i < args.Length; i++) {
				objs [i] = TargetObjectConvert.ImplicitConversionRequired (ctx, args [i], sig.ParameterTypes [i]);
			}

			return Server.Instance.RuntimeInvoke (ctx, function, null, objs);
		}
		public static bool ImplicitConversionExists (MdbEvaluationContext ctx,
							     TargetType source, TargetType target)
		{
			if (source.Equals (target))
				return true;
			
			if (source is TargetArrayType && target.Name == "System.Array")
				return true;

			if (ObjectUtil.FixTypeName (target.Name) == "System.Object")
				return true;
			
			if (source is TargetArrayType && target is TargetArrayType) {
				TargetArrayType sa = (TargetArrayType) source;
				TargetArrayType ta = (TargetArrayType) target;
				return sa.ElementType.Equals (ta.ElementType);
			}
			
			if (source is TargetEnumType) {
				TargetEnumType e = (TargetEnumType) source;
				if (ImplicitConversionExists (ctx, e.Value.Type, target))
					return true;
			}

			if (target is TargetEnumType) {
				TargetEnumType e = (TargetEnumType) target;
				if (ImplicitConversionExists (ctx, source, e.Value.Type))
					return true;
			}

			if ((source is TargetFundamentalType) && (target is TargetFundamentalType))
				return ImplicitFundamentalConversionExists (
					(TargetFundamentalType) source,
					(TargetFundamentalType) target);

			if ((source is TargetClassType) && (target is TargetClassType))
				return ImplicitReferenceConversionExists (
					ctx, (TargetClassType) source,
					(TargetClassType) target);

			return false;
		}
		static bool IsApplicable (MdbEvaluationContext ctx, TargetFunctionType method, TargetType[] types, out string error, out int matchCount)
		{
			TargetMethodSignature sig = method.GetSignature (ctx.Thread);
			matchCount = 0;

			for (int i = 0; i < types.Length; i++) {
				TargetType param_type = sig.ParameterTypes [i];

				if (param_type == types [i]) {
					matchCount++;
					continue;
				}

				if (TargetObjectConvert.ImplicitConversionExists (ctx, types [i], param_type))
					continue;

				error = String.Format (
					"Argument {0}: Cannot implicitly convert `{1}' to `{2}'",
					i, types [i].Name, param_type.Name);
				return false;
			}

			error = null;
			return true;
		}
		public static TargetObject ImplicitConversion (MdbEvaluationContext ctx,
							       TargetObject obj, TargetType type)
		{
			if (obj.Type.Equals (type))
				return obj;
			
			if (type is TargetObjectType || ObjectUtil.FixTypeName (type.Name) == "System.Object") {
				if (obj.Type.IsByRef)
					return obj;
				return BoxValue (ctx, obj);
			}

			if (obj is TargetEnumObject && type is TargetFundamentalType) {
				TargetEnumObject e = (TargetEnumObject) obj;
				return ImplicitConversion (ctx, e.GetValue (ctx.Thread), type);
			}

			if (type is TargetEnumType) {
				TargetEnumType e = (TargetEnumType) type;
				return ImplicitConversion (ctx, obj, e.Value.Type);
			}
			
			if (obj is TargetArrayObject && type.Name == "System.Array") {
				return obj;
			}
			
			if (obj is TargetArrayObject && type is TargetArrayType) {
				TargetArrayObject sa = (TargetArrayObject) obj;
				TargetArrayType ta = (TargetArrayType) type;
				if (sa.Type.ElementType.Equals (ta.ElementType))
					return obj;
			}
			
			if ((obj is TargetFundamentalObject) && (type is TargetFundamentalType))
				return ImplicitFundamentalConversion (
					ctx, (TargetFundamentalObject) obj,
					(TargetFundamentalType) type);

			if ((obj is TargetClassObject) && (type is TargetClassType)) {
				return ImplicitReferenceConversion (
					ctx, (TargetClassObject) obj,
					(TargetClassType) type);
			}

			return null;
		}
		public static TargetObject GetRealObject (MdbEvaluationContext ctx, TargetObject obj)
		{
			if (obj == null)
				return null;

			try {
				switch (obj.Kind) {
					case TargetObjectKind.Array:
					case TargetObjectKind.Fundamental:
						return obj;
						
					case TargetObjectKind.Struct:
					case TargetObjectKind.GenericInstance:
					case TargetObjectKind.Class:
						TargetStructObject co = obj as TargetStructObject;
						if (co == null)
							return null;
						TargetObject res = co.GetCurrentObject (ctx.Thread);
						return res ?? obj;
						
					case TargetObjectKind.Object:
						TargetObjectObject oob = obj as TargetObjectObject;
						if (oob == null)
							return null;
						if (oob.Type.CanDereference)
							return oob.GetDereferencedObject (ctx.Thread);
						else
							return oob;
				}
			}
			catch {
				// Ignore
			}
			return obj;
		}
		public static TargetObject ImplicitConversionRequired (MdbEvaluationContext ctx,
								       TargetObject obj, TargetType type)
		{
			TargetObject new_obj = ImplicitConversion (ctx, obj, type);
			if (new_obj != null)
				return new_obj;

			throw new Exception (string.Format ("Cannot implicitly convert `{0}' to `{1}'", obj.Type.Name, type.Name));
		}
		public static TargetStructObject ToStructObject (MdbEvaluationContext ctx, TargetObject obj)
		{
			TargetStructObject sobj = obj as TargetStructObject;
			if (sobj != null)
				return sobj;

			TargetObjectObject oobj = obj as TargetObjectObject;
			if (oobj != null)
				return oobj.GetClassObject (ctx.Thread);

			TargetArrayObject aobj = obj as TargetArrayObject;
			if ((aobj != null) && aobj.HasClassObject)
				return aobj.GetClassObject (ctx.Thread);

			return null;
		}
예제 #51
0
 public ArrayAdaptor(MdbEvaluationContext ctx, TargetArrayObject array)
 {
     this.ctx   = ctx;
     this.array = array;
 }