using System; using System.Collections.Generic; using System.Linq; using System.Text; using ILRuntime.CLR.Method; using ILRuntime.CLR.TypeSystem; using ILRuntime.Runtime.Intepreter; namespace ILRuntime.Runtime.Enviorment { #region Functions public class CrossBindingFunctionInfo : CrossBindingMethodInfo { static InvocationTypes[] piTypes = new InvocationTypes[] { InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), }; static Type[] pTypes = new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5) }; public delegate TResult InvocationDelegate(ILTypeInstance instance, T1 arg, T2 arg2, T3 arg3, T4 arg4, T5 arg5); public CrossBindingFunctionInfo(string name) : base(name) { } protected override Type ReturnType { get { return typeof(TResult); } } protected override Type[] Parameters { get { return pTypes; } } public InvocationDelegate DoInvoke { get; set; } public TResult Invoke(ILTypeInstance instance, T1 arg, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { EnsureMethod(instance); if (method != null) { invoking = true; TResult res = default(TResult); try { if (DoInvoke != null) res = DoInvoke(instance, arg, arg2, arg3, arg4, arg5); else { using (var ctx = domain.BeginInvoke(method)) { ctx.PushObject(instance); ctx.PushParameter(piTypes[0], arg); ctx.PushParameter(piTypes[1], arg2); ctx.PushParameter(piTypes[2], arg3); ctx.PushParameter(piTypes[3], arg4); ctx.PushParameter(piTypes[4], arg5); ctx.Invoke(); res = ctx.ReadResult(piTypes[5]); } } } finally { invoking = false; } return res; } else return default(TResult); } public override void Invoke(ILTypeInstance instance) { throw new NotSupportedException(); } } public class CrossBindingFunctionInfo : CrossBindingMethodInfo { static InvocationTypes[] piTypes = new InvocationTypes[] { InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), }; static Type[] pTypes = new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }; public delegate TResult InvocationDelegate(ILTypeInstance instance, T1 arg, T2 arg2, T3 arg3, T4 arg4); public CrossBindingFunctionInfo(string name) : base(name) { } protected override Type ReturnType { get { return typeof(TResult); } } protected override Type[] Parameters { get { return pTypes; } } public InvocationDelegate DoInvoke { get; set; } public TResult Invoke(ILTypeInstance instance, T1 arg, T2 arg2, T3 arg3, T4 arg4) { EnsureMethod(instance); if (method != null) { invoking = true; TResult res = default(TResult); try { if (DoInvoke != null) res = DoInvoke(instance, arg, arg2, arg3, arg4); else { using (var ctx = domain.BeginInvoke(method)) { ctx.PushObject(instance); ctx.PushParameter(piTypes[0], arg); ctx.PushParameter(piTypes[1], arg2); ctx.PushParameter(piTypes[2], arg3); ctx.PushParameter(piTypes[3], arg4); ctx.Invoke(); res = ctx.ReadResult(piTypes[4]); } } } finally { invoking = false; } return res; } else return default(TResult); } public override void Invoke(ILTypeInstance instance) { throw new NotSupportedException(); } } public class CrossBindingFunctionInfo : CrossBindingMethodInfo { static InvocationTypes[] piTypes = new InvocationTypes[] { InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), }; static Type[] pTypes = new Type[] { typeof(T1), typeof(T2), typeof(T3) }; public delegate TResult InvocationDelegate(ILTypeInstance instance, T1 arg, T2 arg2, T3 arg3); public CrossBindingFunctionInfo(string name) : base(name) { } protected override Type ReturnType { get { return typeof(TResult); } } protected override Type[] Parameters { get { return pTypes; } } public InvocationDelegate DoInvoke { get; set; } public TResult Invoke(ILTypeInstance instance, T1 arg, T2 arg2, T3 arg3) { EnsureMethod(instance); if (method != null) { invoking = true; TResult res = default(TResult); try { if (DoInvoke != null) res = DoInvoke(instance, arg, arg2, arg3); else { using (var ctx = domain.BeginInvoke(method)) { ctx.PushObject(instance); ctx.PushParameter(piTypes[0], arg); ctx.PushParameter(piTypes[1], arg2); ctx.PushParameter(piTypes[2], arg3); ctx.Invoke(); res = ctx.ReadResult(piTypes[3]); } } } finally { invoking = false; } return res; } else return default(TResult); } public override void Invoke(ILTypeInstance instance) { throw new NotSupportedException(); } } public class CrossBindingFunctionInfo : CrossBindingMethodInfo { static InvocationTypes[] piTypes = new InvocationTypes[] { InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), }; static Type[] pTypes = new Type[] { typeof(T1), typeof(T2) }; public delegate TResult InvocationDelegate(ILTypeInstance instance, T1 arg, T2 arg2); public CrossBindingFunctionInfo(string name) : base(name) { } protected override Type ReturnType { get { return typeof(TResult); } } protected override Type[] Parameters { get { return pTypes; } } public InvocationDelegate DoInvoke { get; set; } public TResult Invoke(ILTypeInstance instance, T1 arg, T2 arg2) { EnsureMethod(instance); if (method != null) { invoking = true; TResult res = default(TResult); try { if (DoInvoke != null) res = DoInvoke(instance, arg, arg2); else { using (var ctx = domain.BeginInvoke(method)) { ctx.PushObject(instance); ctx.PushParameter(piTypes[0], arg); ctx.PushParameter(piTypes[1], arg2); ctx.Invoke(); res = ctx.ReadResult(piTypes[2]); } } } finally { invoking = false; } return res; } else return default(TResult); } public override void Invoke(ILTypeInstance instance) { throw new NotSupportedException(); } } public class CrossBindingFunctionInfo : CrossBindingMethodInfo { static InvocationTypes[] piTypes = new InvocationTypes[] { InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), }; static Type[] pTypes = new Type[] { typeof(T1) }; public delegate TResult InvocationDelegate(ILTypeInstance instance, T1 arg); public CrossBindingFunctionInfo(string name) : base(name) { } protected override Type ReturnType { get { return typeof(TResult); } } protected override Type[] Parameters { get { return pTypes; } } public InvocationDelegate DoInvoke { get; set; } public TResult Invoke(ILTypeInstance instance, T1 arg) { EnsureMethod(instance); if (method != null) { invoking = true; TResult res = default(TResult); try { if (DoInvoke != null) res = DoInvoke(instance, arg); else { using (var ctx = domain.BeginInvoke(method)) { ctx.PushObject(instance); ctx.PushParameter(piTypes[0], arg); ctx.Invoke(); res = ctx.ReadResult(piTypes[1]); } } } finally { invoking = false; } return res; } else return default(TResult); } public override void Invoke(ILTypeInstance instance) { throw new NotSupportedException(); } } public class CrossBindingFunctionInfo : CrossBindingMethodInfo { static InvocationTypes rType = InvocationContext.GetInvocationType(); public delegate TResult InvocationDelegate(ILTypeInstance instance); public CrossBindingFunctionInfo(string name) : base(name) { } protected override Type ReturnType { get { return typeof(TResult); } } public InvocationDelegate DoInvoke { get; set; } public new TResult Invoke(ILTypeInstance instance) { EnsureMethod(instance); if (method != null) { invoking = true; TResult res = default(TResult); try { if (DoInvoke != null) res = DoInvoke(instance); else { using (var ctx = domain.BeginInvoke(method)) { ctx.PushObject(instance); ctx.Invoke(); res = ctx.ReadResult(rType); } } } finally { invoking = false; } return res; } else return default(TResult); } } #endregion #region Methods public class CrossBindingMethodInfo : CrossBindingMethodInfo { static InvocationTypes[] piTypes = new InvocationTypes[] { InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), }; static Type[] pTypes = new Type[] { typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5) }; public delegate void InvocationDelegate(ILTypeInstance instance, T arg, T2 arg2, T3 arg3, T4 arg4, T5 arg5); public CrossBindingMethodInfo(string name) : base(name) { } protected override Type ReturnType { get { return null; } } protected override Type[] Parameters { get { return pTypes; } } public InvocationDelegate DoInvoke { get; set; } public void Invoke(ILTypeInstance instance, T arg, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { EnsureMethod(instance); if (method != null) { invoking = true; try { if (DoInvoke != null) DoInvoke(instance, arg, arg2, arg3, arg4, arg5); else { using (var ctx = domain.BeginInvoke(method)) { ctx.PushObject(instance); ctx.PushParameter(piTypes[0], arg); ctx.PushParameter(piTypes[1], arg2); ctx.PushParameter(piTypes[2], arg3); ctx.PushParameter(piTypes[3], arg4); ctx.PushParameter(piTypes[4], arg5); ctx.Invoke(); } } } finally { invoking = false; } } } public override void Invoke(ILTypeInstance instance) { throw new NotSupportedException(); } } public class CrossBindingMethodInfo : CrossBindingMethodInfo { static InvocationTypes[] piTypes = new InvocationTypes[] { InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), }; static Type[] pTypes = new Type[] { typeof(T), typeof(T2), typeof(T3), typeof(T4) }; public delegate void InvocationDelegate(ILTypeInstance instance, T arg, T2 arg2, T3 arg3, T4 arg4); public CrossBindingMethodInfo(string name) : base(name) { } protected override Type ReturnType { get { return null; } } protected override Type[] Parameters { get { return pTypes; } } public InvocationDelegate DoInvoke { get; set; } public void Invoke(ILTypeInstance instance, T arg, T2 arg2, T3 arg3, T4 arg4) { EnsureMethod(instance); if (method != null) { invoking = true; try { if (DoInvoke != null) DoInvoke(instance, arg, arg2, arg3, arg4); else { using (var ctx = domain.BeginInvoke(method)) { ctx.PushObject(instance); ctx.PushParameter(piTypes[0], arg); ctx.PushParameter(piTypes[1], arg2); ctx.PushParameter(piTypes[2], arg3); ctx.PushParameter(piTypes[3], arg4); ctx.Invoke(); } } } finally { invoking = false; } } } public override void Invoke(ILTypeInstance instance) { throw new NotSupportedException(); } } public class CrossBindingMethodInfo : CrossBindingMethodInfo { static InvocationTypes[] piTypes = new InvocationTypes[] { InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), }; static Type[] pTypes = new Type[] { typeof(T), typeof(T2), typeof(T3) }; public delegate void InvocationDelegate(ILTypeInstance instance, T arg, T2 arg2, T3 arg3); public CrossBindingMethodInfo(string name) : base(name) { } protected override Type ReturnType { get { return null; } } protected override Type[] Parameters { get { return pTypes; } } public InvocationDelegate DoInvoke { get; set; } public void Invoke(ILTypeInstance instance, T arg, T2 arg2, T3 arg3) { EnsureMethod(instance); if (method != null) { invoking = true; try { if (DoInvoke != null) DoInvoke(instance, arg, arg2, arg3); else { using (var ctx = domain.BeginInvoke(method)) { ctx.PushObject(instance); ctx.PushParameter(piTypes[0], arg); ctx.PushParameter(piTypes[1], arg2); ctx.PushParameter(piTypes[2], arg3); ctx.Invoke(); } } } finally { invoking = false; } } } public override void Invoke(ILTypeInstance instance) { throw new NotSupportedException(); } } public class CrossBindingMethodInfo : CrossBindingMethodInfo { static InvocationTypes[] piTypes = new InvocationTypes[] { InvocationContext.GetInvocationType(), InvocationContext.GetInvocationType(), }; static Type[] pTypes = new Type[] { typeof(T), typeof(T2) }; public delegate void InvocationDelegate(ILTypeInstance instance, T arg, T2 arg2); public CrossBindingMethodInfo(string name) : base(name) { } protected override Type ReturnType { get { return null; } } protected override Type[] Parameters { get { return pTypes; } } public InvocationDelegate DoInvoke { get; set; } public void Invoke(ILTypeInstance instance, T arg, T2 arg2) { EnsureMethod(instance); if (method != null) { invoking = true; try { if (DoInvoke != null) DoInvoke(instance, arg, arg2); else { using (var ctx = domain.BeginInvoke(method)) { ctx.PushObject(instance); ctx.PushParameter(piTypes[0], arg); ctx.PushParameter(piTypes[1], arg2); ctx.Invoke(); } } } finally { invoking = false; } } } public override void Invoke(ILTypeInstance instance) { throw new NotSupportedException(); } } public class CrossBindingMethodInfo : CrossBindingMethodInfo { static InvocationTypes piTypes = InvocationContext.GetInvocationType(); static Type[] pTypes = new Type[] { typeof(T) }; public delegate void InvocationDelegate(ILTypeInstance instance, T arg); public CrossBindingMethodInfo(string name) : base(name) { } protected override Type ReturnType { get { return null; } } protected override Type[] Parameters { get { return pTypes; } } public InvocationDelegate DoInvoke { get; set; } public void Invoke(ILTypeInstance instance, T arg) { EnsureMethod(instance); if (method != null) { invoking = true; try { if (DoInvoke != null) DoInvoke(instance, arg); else { using (var ctx = domain.BeginInvoke(method)) { ctx.PushObject(instance); ctx.PushParameter(piTypes, arg); ctx.Invoke(); } } } finally { invoking = false; } } } public override void Invoke(ILTypeInstance instance) { throw new NotSupportedException(); } } #endregion public class CrossBindingMethodInfo { public string Name { get; private set; } protected AppDomain domain; protected IMethod method; private IMethod baseMethod; private bool methodGot; protected bool invoking; static List emptyParam = new List(); public CrossBindingMethodInfo(string name) { Name = name; } protected virtual Type[] Parameters { get { return null; } } protected virtual Type ReturnType { get { return null; } } public bool CheckShouldInvokeBase(ILTypeInstance ins) { EnsureMethod(ins); return method == null || invoking; } protected void EnsureMethod(ILTypeInstance ins) { if (!methodGot) { var ilType = ins.Type; domain = ilType.AppDomain; methodGot = true; List param = null; IType rt = null; if (Parameters != null) { param = new List(); foreach (var i in Parameters) { if (i.IsByRef) { var type = domain.GetType(i.GetElementType()); param.Add(type.MakeByRefType()); } else param.Add(domain.GetType(i)); } } else param = emptyParam; if (ReturnType != null) rt = domain.GetType(ReturnType); if (ilType.FirstCLRBaseType != null) baseMethod = ilType.FirstCLRBaseType.BaseType.GetMethod(Name, param, null, rt); if (ilType.FirstCLRInterface != null) { var implements = ilType.FirstCLRInterface.Implements; for (int i = 0; i < implements.Length; i++) { baseMethod = implements[i].GetMethod(Name, param, null, rt); if (baseMethod != null) break; } } if (baseMethod == null) method = ilType.GetMethod(Name, param, null, rt); } if (baseMethod != null) { method = ins.Type.GetVirtualMethod(baseMethod); if (method is CLRMethod) method = null; } } public virtual void Invoke(ILTypeInstance instance) { EnsureMethod(instance); if (method != null) { invoking = true; try { domain.Invoke(method, instance, null); } finally { invoking = false; } } } } }