public override IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method) { return(new DummyDelegateAdapter(appdomain, instance, method)); }
protected DelegateAdapter(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method) { this.appdomain = appdomain; this.instance = instance; this.method = method; CLRInstance = this; }
public override IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method) { return(new FunctionDelegateAdapter <TResult>(appdomain, instance, method)); }
protected DummyDelegateAdapter(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method) : base(appdomain, instance, method) { }
public abstract IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method);
private MethodDelegateAdapter(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method) : base(appdomain, instance, method) { action = InvokeILMethod; }
unsafe internal void CheckShouldBreak(ILMethod method, ILIntepreter intp, int ip) { if (server != null && server.IsAttached) { int methodHash = method.GetHashCode(); BreakpointInfo[] lst = null; lock (activeBreakpoints) { LinkedList<BreakpointInfo> bps; if (activeBreakpoints.TryGetValue(methodHash, out bps)) lst = bps.ToArray(); } bool bpHit = false; if (lst != null) { var sp = method.Definition.Body.Instructions[ip].SequencePoint; if (sp != null) { foreach (var i in lst) { if ((i.StartLine + 1) == sp.StartLine) { DoBreak(intp, i.BreakpointHashCode, false); bpHit = true; break; } } } } if (!bpHit) { var sp = method.Definition.Body.Instructions[ip].SequencePoint; if (sp != null && IsSequenceValid(sp)) { switch (intp.CurrentStepType) { case StepTypes.Into: DoBreak(intp, 0, true); break; case StepTypes.Over: if (intp.Stack.Frames.Peek().BasePointer <= intp.LastStepFrameBase && ip != intp.LastStepInstructionIndex) { DoBreak(intp, 0, true); } break; case StepTypes.Out: { if (intp.Stack.Frames.Count > 0 && intp.Stack.Frames.Peek().BasePointer < intp.LastStepFrameBase) { DoBreak(intp, 0, true); } } break; } } } } }
internal unsafe void DumpStack(StackObject* esp, RuntimeStack stack) { var start = stack.StackBase; var end = esp + 10; var frames = stack.Frames; var mStack = stack.ManagedStack; var valuePointerEnd = stack.ValueTypeStackPointer; StringBuilder final = new StringBuilder(); HashSet<long> leakVObj = new HashSet<long>(); for (var i = stack.ValueTypeStackBase; i > stack.ValueTypeStackPointer;) { leakVObj.Add((long)i); i = Minus(i, i->ValueLow + 1); } for (var i = start; i <= end; i++) { StringBuilder sb = new StringBuilder(); ILMethod localMethod = null, baseMethod = null; bool isLocal = false; bool isBase = false; int localIdx = 0; if (i == esp) sb.Append("->"); foreach (var j in frames) { if (i >= j.LocalVarPointer && i < j.BasePointer) { isLocal = true; localIdx = (int)(i - j.LocalVarPointer); localMethod = j.Method; } else if (i == j.BasePointer) { isBase = true; baseMethod = j.Method; } } sb.Append(string.Format("(0x{0:X8}) Type:{1} ", (long)i, i->ObjectType)); GetStackObjectText(sb, i, mStack, valuePointerEnd); if (i < esp) { if (i->ObjectType == ObjectTypes.ValueTypeObjectReference) VisitValueTypeReference(*(StackObject**)&i->Value, leakVObj); } if (isLocal) { sb.Append(string.Format("|Loc:{0}", localIdx)); if (localIdx == 0) { sb.Append(" Method:"); sb.Append(localMethod.ToString()); } } if (isBase) { sb.Append("|Base"); sb.Append(" Method:"); sb.Append(baseMethod.ToString()); } final.AppendLine(sb.ToString()); } for (var i = stack.ValueTypeStackBase; i > stack.ValueTypeStackPointer;) { var vt = domain.GetType(i->Value); var cnt = i->ValueLow; bool leak = leakVObj.Contains((long)i); final.AppendLine("----------------------------------------------"); final.AppendLine(string.Format("{2}(0x{0:X8}){1}", (long)i, vt, leak ? "*" : "")); for (int j = 0; j < cnt; j++) { StringBuilder sb = new StringBuilder(); var ptr = Minus(i, j + 1); sb.Append(string.Format("(0x{0:X8}) Type:{1} ", (long)ptr, ptr->ObjectType)); GetStackObjectText(sb, ptr, mStack, valuePointerEnd); final.AppendLine(sb.ToString()); } i = Minus(i, i->ValueLow + 1); } final.AppendLine("Managed Objects:"); for (int i = 0; i < mStack.Count; i++) { final.AppendLine(string.Format("({0}){1}", i, mStack[i])); } #if !UNITY_5 && !UNITY_2017_1_OR_NEWER && !UNITY_4 System.Diagnostics.Debug.Print(final.ToString()); #else UnityEngine.Debug.LogWarning(final.ToString()); #endif }
internal IDelegateAdapter FindDelegateAdapter(ILTypeInstance instance, ILMethod method) { IDelegateAdapter res; if (method.ReturnType == appdomain.VoidType) { if (method.ParameterCount == 0) { res = zeroParamMethodAdapter.Instantiate(appdomain, instance, method); if (instance != null) { instance.SetDelegateAdapter(method, res); } return(res); } foreach (var i in methods) { if (i.ParameterTypes.Length == method.ParameterCount) { bool match = true; for (int j = 0; j < method.ParameterCount; j++) { if (i.ParameterTypes[j] != method.Parameters[j].TypeForCLR) { match = false; break; } } if (match) { res = i.Adapter.Instantiate(appdomain, instance, method); if (instance != null) { instance.SetDelegateAdapter(method, res); } return(res); } } } } else { foreach (var i in functions) { if (i.ParameterTypes.Length == method.ParameterCount + 1) { bool match = true; for (int j = 0; j < method.ParameterCount; j++) { if (i.ParameterTypes[j] != method.Parameters[j].TypeForCLR) { match = false; break; } } if (match) { if (method.ReturnType.TypeForCLR == i.ParameterTypes[method.ParameterCount]) { res = i.Adapter.Instantiate(appdomain, instance, method); if (instance != null) { instance.SetDelegateAdapter(method, res); } return(res); } } } } } res = dummyAdapter.Instantiate(appdomain, instance, method); if (instance != null) { instance.SetDelegateAdapter(method, res); } return(res); }
internal IMethod GetMethod(object token, ILType contextType, ILMethod contextMethod, out bool invalidToken) { string methodname = null; string typename = null; List <IType> paramList = null; int hashCode = token.GetHashCode(); IMethod method; IType[] genericArguments = null; IType returnType; invalidToken = false; bool isConstructor = false; if (mapMethod.TryGetValue(hashCode, out method)) { return(method); } IType type = null; if (token is Mono.Cecil.MethodReference) { Mono.Cecil.MethodReference _ref = (token as Mono.Cecil.MethodReference); if (_ref.FullName == "System.Void System.Object::.ctor()") { mapMethod[hashCode] = null; return(null); } if (_ref.FullName == "System.Void System.Attribute::.ctor()") { mapMethod[hashCode] = null; return(null); } methodname = _ref.Name; var typeDef = _ref.DeclaringType; type = GetType(typeDef, contextType, contextMethod); if (type == null) { throw new KeyNotFoundException("Cannot find type:" + typename); } if (token is Mono.Cecil.MethodDefinition) { var def = _ref as MethodDefinition; isConstructor = def.IsConstructor; } else { isConstructor = methodname == ".ctor"; } if (_ref.IsGenericInstance) { GenericInstanceMethod gim = (GenericInstanceMethod)_ref; genericArguments = new IType[gim.GenericArguments.Count]; for (int i = 0; i < genericArguments.Length; i++) { if (gim.GenericArguments[i].IsGenericParameter) { invalidToken = true; } var gt = GetType(gim.GenericArguments[i], contextType, contextMethod); if (gt == null) { gt = contextMethod.FindGenericArgument(gim.GenericArguments[i].Name); if (gt == null)//This means it contains unresolved generic arguments, which means it's not searching the generic instance { genericArguments = null; break; } else { genericArguments[i] = gt; } } else { genericArguments[i] = gt; } } } if (!invalidToken && typeDef.IsGenericInstance) { GenericInstanceType gim = (GenericInstanceType)typeDef; for (int i = 0; i < gim.GenericArguments.Count; i++) { if (gim.GenericArguments[0].IsGenericParameter) { invalidToken = true; break; } } } paramList = _ref.GetParamList(this, contextType, contextMethod, genericArguments); returnType = GetType(_ref.ReturnType, type, null); if (returnType == null) { returnType = GetType(_ref.ReturnType, contextType, null); } } else { throw new NotImplementedException(); //Mono.Cecil.GenericInstanceMethod gmethod = _def as Mono.Cecil.GenericInstanceMethod; //genlist = new MethodParamList(environment, gmethod); } if (isConstructor) { method = type.GetConstructor(paramList); } else { method = type.GetMethod(methodname, paramList, genericArguments, returnType); } if (method == null) { if (isConstructor && contextType.FirstCLRBaseType != null && contextType.FirstCLRBaseType is CrossBindingAdaptor && type.TypeForCLR == ((CrossBindingAdaptor)contextType.FirstCLRBaseType).BaseCLRType) { method = contextType.BaseType.GetConstructor(paramList); if (method == null) { throw new KeyNotFoundException(string.Format("Cannot find method:{0} in type:{1}, token={2}", methodname, type.FullName, token)); } invalidToken = true; mapMethod[method.GetHashCode()] = method; } else { throw new KeyNotFoundException(string.Format("Cannot find method:{0} in type:{1}, token={2}", methodname, type.FullName, token)); } } if (!invalidToken) { mapMethod[hashCode] = method; } else { mapMethod[method.GetHashCode()] = method; } return(method); }
ILMethod CheckGenericParams(ILMethod i, List <IType> param, IType[] genericArguments, ref bool match) { ILMethod genericMethod = null; if (param != null) { for (int j = 0; j < param.Count; j++) { var p = i.Parameters[j]; if (p.IsGenericParameter) { if (IsGenericArgumentMatch(p, param[j], genericArguments)) { continue; } else { match = false; break; } } if (p.IsByRef) { p = p.ElementType; } if (p.IsArray) { p = p.ElementType; } var p2 = param[j]; if (p2.IsByRef) { p2 = p2.ElementType; } if (p2.IsArray) { p2 = p2.ElementType; } if (p.IsGenericParameter) { if (i.Parameters[j].IsByRef == param[j].IsByRef && i.Parameters[j].IsArray == param[j].IsArray && IsGenericArgumentMatch(p, p2, genericArguments)) { continue; } else { match = false; break; } } if (p.HasGenericParameter) { if (p.Name != p2.Name) { match = false; break; } //TODO should match the generic parameters; continue; } if (p2 != p) { match = false; break; } } } if (match) { genericMethod = i; } return(genericMethod); }
void TryBindBreakpoint(CSBindBreakpoint msg) { var domain = ds.AppDomain; SCBindBreakpointResult res = new Protocol.SCBindBreakpointResult(); res.BreakpointHashCode = msg.BreakpointHashCode; IType type; if (msg.IsLambda) { ILMethod found = null; foreach (var i in domain.LoadedTypes) { var vt = i.Value as ILType; if (vt != null) { if (vt.FullName.Contains(msg.TypeName)) { foreach (var j in vt.GetMethods()) { if (j.Name.Contains(string.Format("<{0}>", msg.MethodName))) { ILMethod ilm = (ILMethod)j; if (ilm.StartLine <= (msg.StartLine + 1) && ilm.EndLine >= (msg.StartLine + 1)) { found = ilm; break; } else if (CheckCompilerGeneratedStateMachine(ilm, domain, msg.StartLine, out found)) { break; } } } } } if (found != null) { break; } } if (found != null) { ds.SetBreakPoint(found.GetHashCode(), msg.BreakpointHashCode, msg.StartLine); res.Result = BindBreakpointResults.OK; } else { res.Result = BindBreakpointResults.CodeNotFound; } } else { if (domain.LoadedTypes.TryGetValue(msg.TypeName, out type)) { if (type is ILType) { ILType it = (ILType)type; ILMethod found = null; if (msg.MethodName == ".ctor") { foreach (var i in it.GetConstructors()) { ILMethod ilm = (ILMethod)i; if (ilm.StartLine <= (msg.StartLine + 1) && ilm.EndLine >= (msg.StartLine + 1)) { found = ilm; break; } } } else if (msg.MethodName == ".cctor") { ILMethod ilm = it.GetStaticConstroctor() as ILMethod; if (ilm.StartLine <= (msg.StartLine + 1) && ilm.EndLine >= (msg.StartLine + 1)) { found = ilm; } } else { foreach (var i in it.GetMethods()) { if (i.Name == msg.MethodName) { ILMethod ilm = (ILMethod)i; if (ilm.StartLine <= (msg.StartLine + 1) && ilm.EndLine >= (msg.StartLine + 1)) { found = ilm; break; } else if (CheckCompilerGeneratedStateMachine(ilm, domain, msg.StartLine, out found)) { break; } } } } if (found != null) { ds.SetBreakPoint(found.GetHashCode(), msg.BreakpointHashCode, msg.StartLine); res.Result = BindBreakpointResults.OK; } else { res.Result = BindBreakpointResults.CodeNotFound; } } else { res.Result = BindBreakpointResults.TypeNotFound; } } else { res.Result = BindBreakpointResults.TypeNotFound; } } SendSCBindBreakpointResult(res); }
bool CheckCompilerGeneratedStateMachine(ILMethod ilm, Enviorment.AppDomain domain, int startLine, out ILMethod found) { var mDef = ilm.Definition; Mono.Cecil.CustomAttribute ca = null; found = null; foreach (var attr in mDef.CustomAttributes) { switch (attr.AttributeType.FullName) { case "System.Runtime.CompilerServices.AsyncStateMachineAttribute": case "System.Runtime.CompilerServices.IteratorStateMachineAttribute": ca = attr; break; } } if (ca != null) { if (ca.ConstructorArguments.Count > 0) { var smType = domain.GetType(ca.ConstructorArguments[0].Value, null, null); if (smType != null) { ilm = smType.GetMethod("MoveNext", 0, true) as ILMethod; if (ilm != null && ilm.StartLine <= (startLine + 1) && ilm.EndLine >= (startLine + 1)) { found = ilm; return(true); } } } } return(false); }