You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1227 lines
36 KiB
1227 lines
36 KiB
3 years ago
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
using System.Text;
|
||
|
using ILRuntime.CLR.TypeSystem;
|
||
|
using ILRuntime.CLR.Method;
|
||
|
using ILRuntime.Runtime;
|
||
|
using ILRuntime.Runtime.Stack;
|
||
|
using ILRuntime.Other;
|
||
|
using ILRuntime.Runtime.Enviorment;
|
||
|
|
||
|
namespace ILRuntime.Runtime.Intepreter
|
||
|
{
|
||
|
#region Functions
|
||
|
class FunctionDelegateAdapter<TResult> : DelegateAdapter
|
||
|
{
|
||
|
Func<TResult> action;
|
||
|
|
||
|
static InvocationTypes[] pTypes;
|
||
|
static FunctionDelegateAdapter()
|
||
|
{
|
||
|
pTypes = new InvocationTypes[]
|
||
|
{
|
||
|
InvocationContext.GetInvocationType<TResult>(),
|
||
|
};
|
||
|
}
|
||
|
public FunctionDelegateAdapter()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
private FunctionDelegateAdapter(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
: base(appdomain, instance, method)
|
||
|
{
|
||
|
action = InvokeILMethod;
|
||
|
}
|
||
|
|
||
|
public override Type NativeDelegateType
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return typeof(Func<TResult>);
|
||
|
}
|
||
|
}
|
||
|
public override Delegate Delegate
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return action;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsafe TResult InvokeILMethod()
|
||
|
{
|
||
|
using (var ctx = BeginInvoke())
|
||
|
{
|
||
|
var esp = ILInvoke(ctx.Intepreter, ctx.ESP, ctx.ManagedStack);
|
||
|
ctx.SetInvoked(esp);
|
||
|
return ctx.ReadResult<TResult>(pTypes[0]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
{
|
||
|
return new FunctionDelegateAdapter<TResult>(appdomain, instance, method);
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Clone()
|
||
|
{
|
||
|
var res = new FunctionDelegateAdapter<TResult>(appdomain, instance, method);
|
||
|
res.isClone = true;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
public override void Combine(Delegate dele)
|
||
|
{
|
||
|
action += (Func<TResult>)dele;
|
||
|
}
|
||
|
|
||
|
public override void Remove(Delegate dele)
|
||
|
{
|
||
|
action -= (Func<TResult>)dele;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class FunctionDelegateAdapter<T1, TResult> : DelegateAdapter
|
||
|
{
|
||
|
Func<T1, TResult> action;
|
||
|
|
||
|
static InvocationTypes[] pTypes;
|
||
|
static FunctionDelegateAdapter()
|
||
|
{
|
||
|
pTypes = new InvocationTypes[]
|
||
|
{
|
||
|
InvocationContext.GetInvocationType<T1>(),
|
||
|
InvocationContext.GetInvocationType<TResult>(),
|
||
|
};
|
||
|
}
|
||
|
public FunctionDelegateAdapter()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
private FunctionDelegateAdapter(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
: base(appdomain, instance, method)
|
||
|
{
|
||
|
action = InvokeILMethod;
|
||
|
}
|
||
|
public override Type NativeDelegateType
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return typeof(Func<T1, TResult>);
|
||
|
}
|
||
|
}
|
||
|
public override Delegate Delegate
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return action;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsafe TResult InvokeILMethod(T1 p1)
|
||
|
{
|
||
|
using (var ctx = BeginInvoke())
|
||
|
{
|
||
|
ctx.PushParameter(pTypes[0], p1);
|
||
|
|
||
|
var esp = ILInvoke(ctx.Intepreter, ctx.ESP, ctx.ManagedStack);
|
||
|
ctx.SetInvoked(esp);
|
||
|
return ctx.ReadResult<TResult>(pTypes[1]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
{
|
||
|
return new FunctionDelegateAdapter<T1, TResult>(appdomain, instance, method);
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Clone()
|
||
|
{
|
||
|
var res = new FunctionDelegateAdapter<T1, TResult>(appdomain, instance, method);
|
||
|
res.isClone = true;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
public override void Combine(Delegate dele)
|
||
|
{
|
||
|
action += (Func<T1, TResult>)dele;
|
||
|
}
|
||
|
|
||
|
public override void Remove(Delegate dele)
|
||
|
{
|
||
|
action -= (Func<T1, TResult>)dele;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class FunctionDelegateAdapter<T1, T2, TResult> : DelegateAdapter
|
||
|
{
|
||
|
Func<T1, T2, TResult> action;
|
||
|
|
||
|
static InvocationTypes[] pTypes;
|
||
|
static FunctionDelegateAdapter()
|
||
|
{
|
||
|
pTypes = new InvocationTypes[]
|
||
|
{
|
||
|
InvocationContext.GetInvocationType<T1>(),
|
||
|
InvocationContext.GetInvocationType<T2>(),
|
||
|
InvocationContext.GetInvocationType<TResult>(),
|
||
|
};
|
||
|
}
|
||
|
public FunctionDelegateAdapter()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
private FunctionDelegateAdapter(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
: base(appdomain, instance, method)
|
||
|
{
|
||
|
action = InvokeILMethod;
|
||
|
}
|
||
|
public override Type NativeDelegateType
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return typeof(Func<T1, T2, TResult>);
|
||
|
}
|
||
|
}
|
||
|
public override Delegate Delegate
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return action;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsafe TResult InvokeILMethod(T1 p1, T2 p2)
|
||
|
{
|
||
|
using (var ctx = BeginInvoke())
|
||
|
{
|
||
|
ctx.PushParameter(pTypes[0], p1);
|
||
|
ctx.PushParameter(pTypes[1], p2);
|
||
|
|
||
|
var esp = ILInvoke(ctx.Intepreter, ctx.ESP, ctx.ManagedStack);
|
||
|
ctx.SetInvoked(esp);
|
||
|
return ctx.ReadResult<TResult>(pTypes[2]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
{
|
||
|
return new FunctionDelegateAdapter<T1, T2, TResult>(appdomain, instance, method);
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Clone()
|
||
|
{
|
||
|
var res = new FunctionDelegateAdapter<T1, T2, TResult>(appdomain, instance, method);
|
||
|
res.isClone = true;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
public override void Combine(Delegate dele)
|
||
|
{
|
||
|
action += (Func<T1, T2, TResult>)dele;
|
||
|
}
|
||
|
|
||
|
public override void Remove(Delegate dele)
|
||
|
{
|
||
|
action -= (Func<T1, T2, TResult>)dele;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class FunctionDelegateAdapter<T1, T2, T3, TResult> : DelegateAdapter
|
||
|
{
|
||
|
Func<T1, T2, T3, TResult> action;
|
||
|
|
||
|
static InvocationTypes[] pTypes;
|
||
|
|
||
|
static FunctionDelegateAdapter()
|
||
|
{
|
||
|
pTypes = new InvocationTypes[]
|
||
|
{
|
||
|
InvocationContext.GetInvocationType<T1>(),
|
||
|
InvocationContext.GetInvocationType<T2>(),
|
||
|
InvocationContext.GetInvocationType<T3>(),
|
||
|
InvocationContext.GetInvocationType<TResult>(),
|
||
|
};
|
||
|
}
|
||
|
public FunctionDelegateAdapter()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
private FunctionDelegateAdapter(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
: base(appdomain, instance, method)
|
||
|
{
|
||
|
action = InvokeILMethod;
|
||
|
}
|
||
|
public override Type NativeDelegateType
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return typeof(Func<T1, T2, T3, TResult>);
|
||
|
}
|
||
|
}
|
||
|
public override Delegate Delegate
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return action;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsafe TResult InvokeILMethod(T1 p1, T2 p2, T3 p3)
|
||
|
{
|
||
|
using (var ctx = BeginInvoke())
|
||
|
{
|
||
|
ctx.PushParameter(pTypes[0], p1);
|
||
|
ctx.PushParameter(pTypes[1], p2);
|
||
|
ctx.PushParameter(pTypes[2], p3);
|
||
|
|
||
|
var esp = ILInvoke(ctx.Intepreter, ctx.ESP, ctx.ManagedStack);
|
||
|
ctx.SetInvoked(esp);
|
||
|
return ctx.ReadResult<TResult>(pTypes[3]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
{
|
||
|
return new FunctionDelegateAdapter<T1, T2, T3, TResult>(appdomain, instance, method);
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Clone()
|
||
|
{
|
||
|
var res = new FunctionDelegateAdapter<T1, T2, T3, TResult>(appdomain, instance, method);
|
||
|
res.isClone = true;
|
||
|
return res;
|
||
|
}
|
||
|
public override void Combine(Delegate dele)
|
||
|
{
|
||
|
action += (Func<T1, T2, T3, TResult>)dele;
|
||
|
}
|
||
|
|
||
|
public override void Remove(Delegate dele)
|
||
|
{
|
||
|
action -= (Func<T1, T2, T3, TResult>)dele;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class FunctionDelegateAdapter<T1, T2, T3, T4, TResult> : DelegateAdapter
|
||
|
{
|
||
|
Func<T1, T2, T3, T4, TResult> action;
|
||
|
|
||
|
static InvocationTypes[] pTypes;
|
||
|
|
||
|
static FunctionDelegateAdapter()
|
||
|
{
|
||
|
pTypes = new InvocationTypes[]
|
||
|
{
|
||
|
InvocationContext.GetInvocationType<T1>(),
|
||
|
InvocationContext.GetInvocationType<T2>(),
|
||
|
InvocationContext.GetInvocationType<T3>(),
|
||
|
InvocationContext.GetInvocationType<T4>(),
|
||
|
InvocationContext.GetInvocationType<TResult>(),
|
||
|
};
|
||
|
}
|
||
|
public FunctionDelegateAdapter()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
private FunctionDelegateAdapter(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
: base(appdomain, instance, method)
|
||
|
{
|
||
|
action = InvokeILMethod;
|
||
|
}
|
||
|
public override Type NativeDelegateType
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return typeof(Func<T1, T2, T3, T4, TResult>);
|
||
|
}
|
||
|
}
|
||
|
public override Delegate Delegate
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return action;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsafe TResult InvokeILMethod(T1 p1, T2 p2, T3 p3, T4 p4)
|
||
|
{
|
||
|
using (var ctx = BeginInvoke())
|
||
|
{
|
||
|
ctx.PushParameter(pTypes[0], p1);
|
||
|
ctx.PushParameter(pTypes[1], p2);
|
||
|
ctx.PushParameter(pTypes[2], p3);
|
||
|
ctx.PushParameter(pTypes[3], p4);
|
||
|
|
||
|
var esp = ILInvoke(ctx.Intepreter, ctx.ESP, ctx.ManagedStack);
|
||
|
ctx.SetInvoked(esp);
|
||
|
return ctx.ReadResult<TResult>(pTypes[4]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
{
|
||
|
return new FunctionDelegateAdapter<T1, T2, T3, T4, TResult>(appdomain, instance, method);
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Clone()
|
||
|
{
|
||
|
var res = new FunctionDelegateAdapter<T1, T2, T3, T4, TResult>(appdomain, instance, method);
|
||
|
res.isClone = true;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
public override void Combine(Delegate dele)
|
||
|
{
|
||
|
action += (Func<T1, T2, T3, T4, TResult>)dele;
|
||
|
}
|
||
|
|
||
|
public override void Remove(Delegate dele)
|
||
|
{
|
||
|
action -= (Func<T1, T2, T3, T4, TResult>)dele;
|
||
|
}
|
||
|
}
|
||
|
#endregion
|
||
|
|
||
|
#region Methods
|
||
|
class MethodDelegateAdapter<T1> : DelegateAdapter
|
||
|
{
|
||
|
Action<T1> action;
|
||
|
static InvocationTypes pType;
|
||
|
|
||
|
static MethodDelegateAdapter()
|
||
|
{
|
||
|
pType = InvocationContext.GetInvocationType<T1>();
|
||
|
}
|
||
|
|
||
|
public MethodDelegateAdapter()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
private MethodDelegateAdapter(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
: base(appdomain, instance, method)
|
||
|
{
|
||
|
action = InvokeILMethod;
|
||
|
}
|
||
|
|
||
|
public override Type NativeDelegateType
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return typeof(Action<T1>);
|
||
|
}
|
||
|
}
|
||
|
public override Delegate Delegate
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return action;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsafe void InvokeILMethod(T1 p1)
|
||
|
{
|
||
|
using (var ctx = BeginInvoke())
|
||
|
{
|
||
|
ctx.PushParameter(pType, p1);
|
||
|
ILInvoke(ctx.Intepreter, ctx.ESP, ctx.ManagedStack);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
{
|
||
|
return new MethodDelegateAdapter<T1>(appdomain, instance, method);
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Clone()
|
||
|
{
|
||
|
var res = new MethodDelegateAdapter<T1>(appdomain, instance, method);
|
||
|
res.isClone = true;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
public override void Combine(Delegate dele)
|
||
|
{
|
||
|
action += (Action<T1>)dele;
|
||
|
}
|
||
|
|
||
|
public override void Remove(Delegate dele)
|
||
|
{
|
||
|
action -= (Action<T1>)dele;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class MethodDelegateAdapter<T1, T2> : DelegateAdapter
|
||
|
{
|
||
|
Action<T1, T2> action;
|
||
|
|
||
|
static InvocationTypes[] pTypes;
|
||
|
|
||
|
static MethodDelegateAdapter()
|
||
|
{
|
||
|
pTypes = new InvocationTypes[]
|
||
|
{
|
||
|
InvocationContext.GetInvocationType<T1>(),
|
||
|
InvocationContext.GetInvocationType<T2>(),
|
||
|
};
|
||
|
}
|
||
|
public MethodDelegateAdapter()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
private MethodDelegateAdapter(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
: base(appdomain, instance, method)
|
||
|
{
|
||
|
action = InvokeILMethod;
|
||
|
}
|
||
|
public override Type NativeDelegateType
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return typeof(Action<T1, T2>);
|
||
|
}
|
||
|
}
|
||
|
public override Delegate Delegate
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return action;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsafe void InvokeILMethod(T1 p1, T2 p2)
|
||
|
{
|
||
|
using (var ctx = BeginInvoke())
|
||
|
{
|
||
|
ctx.PushParameter(pTypes[0], p1);
|
||
|
ctx.PushParameter(pTypes[1], p2);
|
||
|
ILInvoke(ctx.Intepreter, ctx.ESP, ctx.ManagedStack);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
{
|
||
|
return new MethodDelegateAdapter<T1, T2>(appdomain, instance, method);
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Clone()
|
||
|
{
|
||
|
var res = new MethodDelegateAdapter<T1, T2>(appdomain, instance, method);
|
||
|
res.isClone = true;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
public override void Combine(Delegate dele)
|
||
|
{
|
||
|
action += (Action<T1, T2>)dele;
|
||
|
}
|
||
|
|
||
|
public override void Remove(Delegate dele)
|
||
|
{
|
||
|
action -= (Action<T1, T2>)dele;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class MethodDelegateAdapter<T1, T2, T3> : DelegateAdapter
|
||
|
{
|
||
|
Action<T1, T2, T3> action;
|
||
|
|
||
|
static InvocationTypes[] pTypes;
|
||
|
|
||
|
static MethodDelegateAdapter()
|
||
|
{
|
||
|
pTypes = new InvocationTypes[]
|
||
|
{
|
||
|
InvocationContext.GetInvocationType<T1>(),
|
||
|
InvocationContext.GetInvocationType<T2>(),
|
||
|
InvocationContext.GetInvocationType<T3>(),
|
||
|
};
|
||
|
}
|
||
|
public MethodDelegateAdapter()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
private MethodDelegateAdapter(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
: base(appdomain, instance, method)
|
||
|
{
|
||
|
action = InvokeILMethod;
|
||
|
}
|
||
|
public override Type NativeDelegateType
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return typeof(Action<T1, T2, T3>);
|
||
|
}
|
||
|
}
|
||
|
public override Delegate Delegate
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return action;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsafe void InvokeILMethod(T1 p1, T2 p2, T3 p3)
|
||
|
{
|
||
|
using (var ctx = BeginInvoke())
|
||
|
{
|
||
|
ctx.PushParameter(pTypes[0], p1);
|
||
|
ctx.PushParameter(pTypes[1], p2);
|
||
|
ctx.PushParameter(pTypes[2], p3);
|
||
|
ILInvoke(ctx.Intepreter, ctx.ESP, ctx.ManagedStack);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
{
|
||
|
return new MethodDelegateAdapter<T1, T2, T3>(appdomain, instance, method);
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Clone()
|
||
|
{
|
||
|
var res = new MethodDelegateAdapter<T1, T2, T3>(appdomain, instance, method);
|
||
|
res.isClone = true;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
public override void Combine(Delegate dele)
|
||
|
{
|
||
|
action += (Action<T1, T2, T3>)dele;
|
||
|
}
|
||
|
|
||
|
public override void Remove(Delegate dele)
|
||
|
{
|
||
|
action -= (Action<T1, T2, T3>)dele;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class MethodDelegateAdapter<T1, T2, T3, T4> : DelegateAdapter
|
||
|
{
|
||
|
Action<T1, T2, T3, T4> action;
|
||
|
|
||
|
static InvocationTypes[] pTypes;
|
||
|
|
||
|
static MethodDelegateAdapter()
|
||
|
{
|
||
|
pTypes = new InvocationTypes[]
|
||
|
{
|
||
|
InvocationContext.GetInvocationType<T1>(),
|
||
|
InvocationContext.GetInvocationType<T2>(),
|
||
|
InvocationContext.GetInvocationType<T3>(),
|
||
|
InvocationContext.GetInvocationType<T4>(),
|
||
|
};
|
||
|
}
|
||
|
public MethodDelegateAdapter()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
private MethodDelegateAdapter(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
: base(appdomain, instance, method)
|
||
|
{
|
||
|
action = InvokeILMethod;
|
||
|
}
|
||
|
public override Type NativeDelegateType
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return typeof(Action<T1, T2, T3, T4>);
|
||
|
}
|
||
|
}
|
||
|
public override Delegate Delegate
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return action;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsafe void InvokeILMethod(T1 p1, T2 p2, T3 p3, T4 p4)
|
||
|
{
|
||
|
using (var ctx = BeginInvoke())
|
||
|
{
|
||
|
ctx.PushParameter(pTypes[0], p1);
|
||
|
ctx.PushParameter(pTypes[1], p2);
|
||
|
ctx.PushParameter(pTypes[2], p3);
|
||
|
ctx.PushParameter(pTypes[3], p4);
|
||
|
ILInvoke(ctx.Intepreter, ctx.ESP, ctx.ManagedStack);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
{
|
||
|
return new MethodDelegateAdapter<T1, T2, T3, T4>(appdomain, instance, method);
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Clone()
|
||
|
{
|
||
|
var res = new MethodDelegateAdapter<T1, T2, T3, T4>(appdomain, instance, method);
|
||
|
res.isClone = true;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
public override void Combine(Delegate dele)
|
||
|
{
|
||
|
action += (Action<T1, T2, T3, T4>)dele;
|
||
|
}
|
||
|
|
||
|
public override void Remove(Delegate dele)
|
||
|
{
|
||
|
action -= (Action<T1, T2, T3, T4>)dele;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if NET_4_6 || NET_STANDARD_2_0
|
||
|
class MethodDelegateAdapter<T1, T2, T3, T4, T5> : DelegateAdapter
|
||
|
{
|
||
|
Action<T1, T2, T3, T4, T5> action;
|
||
|
|
||
|
static InvocationTypes[] pTypes;
|
||
|
|
||
|
static MethodDelegateAdapter()
|
||
|
{
|
||
|
pTypes = new InvocationTypes[]
|
||
|
{
|
||
|
InvocationContext.GetInvocationType<T1>(),
|
||
|
InvocationContext.GetInvocationType<T2>(),
|
||
|
InvocationContext.GetInvocationType<T3>(),
|
||
|
InvocationContext.GetInvocationType<T4>(),
|
||
|
InvocationContext.GetInvocationType<T5>(),
|
||
|
};
|
||
|
}
|
||
|
public MethodDelegateAdapter()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
private MethodDelegateAdapter(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
: base(appdomain, instance, method)
|
||
|
{
|
||
|
action = InvokeILMethod;
|
||
|
}
|
||
|
public override Type NativeDelegateType
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return typeof(Action<T1, T2, T3, T4, T5>);
|
||
|
}
|
||
|
}
|
||
|
public override Delegate Delegate
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return action;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsafe void InvokeILMethod(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5)
|
||
|
{
|
||
|
using (var ctx = BeginInvoke())
|
||
|
{
|
||
|
ctx.PushParameter(pTypes[0], p1);
|
||
|
ctx.PushParameter(pTypes[1], p2);
|
||
|
ctx.PushParameter(pTypes[2], p3);
|
||
|
ctx.PushParameter(pTypes[3], p4);
|
||
|
ctx.PushParameter(pTypes[4], p5);
|
||
|
ILInvoke(ctx.Intepreter, ctx.ESP, ctx.ManagedStack);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
{
|
||
|
return new MethodDelegateAdapter<T1, T2, T3, T4, T5>(appdomain, instance, method);
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Clone()
|
||
|
{
|
||
|
var res = new MethodDelegateAdapter<T1, T2, T3, T4, T5>(appdomain, instance, method);
|
||
|
res.isClone = true;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
public override void Combine(Delegate dele)
|
||
|
{
|
||
|
action += (Action<T1, T2, T3, T4, T5>)dele;
|
||
|
}
|
||
|
|
||
|
public override void Remove(Delegate dele)
|
||
|
{
|
||
|
action -= (Action<T1, T2, T3, T4, T5>)dele;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
class MethodDelegateAdapter : DelegateAdapter
|
||
|
{
|
||
|
Action action;
|
||
|
|
||
|
public MethodDelegateAdapter()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
protected MethodDelegateAdapter(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
: base(appdomain, instance, method)
|
||
|
{
|
||
|
action = InvokeILMethod;
|
||
|
}
|
||
|
public override Type NativeDelegateType
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return typeof(Action);
|
||
|
}
|
||
|
}
|
||
|
public override Delegate Delegate
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return action;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsafe void InvokeILMethod()
|
||
|
{
|
||
|
using(var ctx = BeginInvoke())
|
||
|
{
|
||
|
ILInvoke(ctx.Intepreter, ctx.ESP, ctx.ManagedStack);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
{
|
||
|
return new MethodDelegateAdapter(appdomain, instance, method);
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Clone()
|
||
|
{
|
||
|
var res = new MethodDelegateAdapter(appdomain, instance, method);
|
||
|
res.isClone = true;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
public override void Combine(Delegate dele)
|
||
|
{
|
||
|
action += (Action)dele;
|
||
|
}
|
||
|
|
||
|
public override void Remove(Delegate dele)
|
||
|
{
|
||
|
action -= (Action)dele;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class DummyDelegateAdapter : DelegateAdapter
|
||
|
{
|
||
|
public DummyDelegateAdapter()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
protected DummyDelegateAdapter(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
: base(appdomain, instance, method)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
public override Type NativeDelegateType
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
throw new NotSupportedException();
|
||
|
}
|
||
|
}
|
||
|
public override Delegate Delegate
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
ThrowAdapterNotFound(method);
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void InvokeILMethod()
|
||
|
{
|
||
|
if (method.HasThis)
|
||
|
appdomain.Invoke(method, instance, null);
|
||
|
else
|
||
|
appdomain.Invoke(method, null, null);
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
{
|
||
|
return new DummyDelegateAdapter(appdomain, instance, method);
|
||
|
}
|
||
|
|
||
|
public override IDelegateAdapter Clone()
|
||
|
{
|
||
|
var res = new DummyDelegateAdapter(appdomain, instance, method);
|
||
|
res.isClone = true;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
public override void Combine(Delegate dele)
|
||
|
{
|
||
|
ThrowAdapterNotFound(method);
|
||
|
}
|
||
|
|
||
|
public override void Remove(Delegate dele)
|
||
|
{
|
||
|
ThrowAdapterNotFound(method);
|
||
|
}
|
||
|
}
|
||
|
#endregion
|
||
|
|
||
|
abstract class DelegateAdapter : ILTypeInstance, IDelegateAdapter
|
||
|
{
|
||
|
protected ILMethod method;
|
||
|
protected ILTypeInstance instance;
|
||
|
protected Enviorment.AppDomain appdomain;
|
||
|
Dictionary<Type, Delegate> converters;
|
||
|
IDelegateAdapter next;
|
||
|
protected bool isClone;
|
||
|
|
||
|
public abstract Delegate Delegate { get; }
|
||
|
|
||
|
public abstract Type NativeDelegateType { get; }
|
||
|
|
||
|
public IDelegateAdapter Next { get { return next; } }
|
||
|
|
||
|
public ILTypeInstance Instance { get { return instance; } }
|
||
|
|
||
|
public ILMethod Method { get { return method; } }
|
||
|
|
||
|
protected DelegateAdapter() { }
|
||
|
|
||
|
protected DelegateAdapter(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method)
|
||
|
{
|
||
|
this.appdomain = appdomain;
|
||
|
this.instance = instance;
|
||
|
this.method = method;
|
||
|
CLRInstance = this;
|
||
|
}
|
||
|
|
||
|
public override bool IsValueType
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsafe protected InvocationContext BeginInvoke()
|
||
|
{
|
||
|
var ctx = appdomain.BeginInvoke(method);
|
||
|
*ctx.ESP = default(StackObject);
|
||
|
ctx.ESP++;//required to simulate delegate invocation
|
||
|
return ctx;
|
||
|
}
|
||
|
|
||
|
public unsafe StackObject* ILInvoke(ILIntepreter intp, StackObject* esp, IList<object> mStack)
|
||
|
{
|
||
|
var ebp = esp;
|
||
|
esp = ILInvokeSub(intp, esp, mStack);
|
||
|
return ClearStack(intp, esp, ebp, mStack);
|
||
|
}
|
||
|
|
||
|
unsafe StackObject* ILInvokeSub(ILIntepreter intp, StackObject* esp, IList<object> mStack)
|
||
|
{
|
||
|
var ebp = esp;
|
||
|
bool unhandled;
|
||
|
if (method.HasThis)
|
||
|
esp = ILIntepreter.PushObject(esp, mStack, instance);
|
||
|
int paramCnt = method.ParameterCount;
|
||
|
if (method.IsExtend && instance != null)
|
||
|
{
|
||
|
esp = ILIntepreter.PushObject(esp, mStack, instance);
|
||
|
paramCnt--;
|
||
|
}
|
||
|
bool useRegister = method.ShouldUseRegisterVM;
|
||
|
for (int i = paramCnt; i > 0; i--)
|
||
|
{
|
||
|
intp.CopyToStack(esp, Minus(ebp, i), mStack);
|
||
|
if (esp->ObjectType < ObjectTypes.Object && useRegister)
|
||
|
mStack.Add(null);
|
||
|
esp++;
|
||
|
}
|
||
|
StackObject* ret;
|
||
|
if (useRegister)
|
||
|
ret = intp.ExecuteR(method, esp, out unhandled);
|
||
|
else
|
||
|
ret = intp.Execute(method, esp, out unhandled);
|
||
|
if (next != null)
|
||
|
{
|
||
|
if (method.ReturnType != appdomain.VoidType)
|
||
|
{
|
||
|
intp.Free(ret - 1);//Return value for multicast delegate doesn't make sense, only return the last one's value
|
||
|
}
|
||
|
DelegateAdapter n = (DelegateAdapter)next;
|
||
|
ret = n.ILInvokeSub(intp, ebp, mStack);
|
||
|
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
unsafe StackObject* ClearStack(ILIntepreter intp, StackObject* esp, StackObject* ebp, IList<object> mStack)
|
||
|
{
|
||
|
int paramCnt = method.ParameterCount;
|
||
|
if (method.IsExtend && instance != null)//如果是拓展方法,退一位
|
||
|
{
|
||
|
paramCnt--;
|
||
|
}
|
||
|
object retObj = null;
|
||
|
StackObject retSObj = StackObject.Null;
|
||
|
bool hasReturn = method.ReturnType != appdomain.VoidType;
|
||
|
if (hasReturn)
|
||
|
{
|
||
|
var ret = esp - 1;
|
||
|
retSObj = *ret;
|
||
|
if(ret->ObjectType>= ObjectTypes.Object)
|
||
|
{
|
||
|
retObj = mStack[ret->Value];
|
||
|
if(retObj == null)
|
||
|
{
|
||
|
retSObj.ObjectType = ObjectTypes.Null;
|
||
|
retSObj.Value = -1;
|
||
|
retSObj.ValueLow = 0;
|
||
|
}
|
||
|
|
||
|
intp.Free(ret);
|
||
|
}
|
||
|
}
|
||
|
for (int i = 1; i <= paramCnt; i++)
|
||
|
{
|
||
|
intp.Free(ebp - i);
|
||
|
}
|
||
|
var returnVal = Minus(ebp, paramCnt + 1);
|
||
|
intp.Free(returnVal);//Free delegateInstance
|
||
|
if (hasReturn)
|
||
|
{
|
||
|
*returnVal = retSObj;
|
||
|
if(retObj != null)
|
||
|
{
|
||
|
returnVal->Value = mStack.Count;
|
||
|
mStack.Add(retObj);
|
||
|
}
|
||
|
returnVal++;
|
||
|
}
|
||
|
return returnVal;
|
||
|
}
|
||
|
|
||
|
public abstract IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method);
|
||
|
|
||
|
public new abstract IDelegateAdapter Clone();
|
||
|
|
||
|
public bool IsClone
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return isClone;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public virtual void Combine(IDelegateAdapter adapter)
|
||
|
{
|
||
|
if (next != null)
|
||
|
next.Combine(adapter);
|
||
|
else
|
||
|
next = adapter;
|
||
|
}
|
||
|
|
||
|
public abstract void Combine(Delegate dele);
|
||
|
|
||
|
public virtual void Remove(IDelegateAdapter adapter)
|
||
|
{
|
||
|
if (next != null)
|
||
|
{
|
||
|
if (next.Equals(adapter))
|
||
|
{
|
||
|
next = ((DelegateAdapter)next).next;
|
||
|
}
|
||
|
else
|
||
|
next.Remove(adapter);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public abstract void Remove(Delegate dele);
|
||
|
|
||
|
public virtual bool Equals(IDelegateAdapter adapter)
|
||
|
{
|
||
|
if (adapter is DelegateAdapter)
|
||
|
{
|
||
|
DelegateAdapter b = (DelegateAdapter)adapter;
|
||
|
return instance == b.instance && method == b.method;
|
||
|
}
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public override bool Equals(object obj)
|
||
|
{
|
||
|
if (obj is DelegateAdapter)
|
||
|
{
|
||
|
DelegateAdapter b = (DelegateAdapter)obj;
|
||
|
return instance == b.instance && method == b.method;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public virtual bool Equals(Delegate dele)
|
||
|
{
|
||
|
return Delegate == dele;
|
||
|
}
|
||
|
|
||
|
public override int GetHashCode()
|
||
|
{
|
||
|
return base.GetHashCode();
|
||
|
}
|
||
|
|
||
|
public override string ToString()
|
||
|
{
|
||
|
return method.ToString();
|
||
|
}
|
||
|
|
||
|
public override bool CanAssignTo(IType type)
|
||
|
{
|
||
|
if (type.IsDelegate)
|
||
|
{
|
||
|
var method_count = method.IsExtend ? method.ParameterCount - 1 : method.ParameterCount;
|
||
|
var im = type.GetMethod("Invoke", method_count);
|
||
|
if (im == null)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
var ret_type = im.ReturnType;
|
||
|
if (im.ReturnType != appdomain.VoidType && type.IsGenericInstance)
|
||
|
{
|
||
|
ret_type = type.GenericArguments[im.ParameterCount].Value;
|
||
|
}
|
||
|
if (im.IsDelegateInvoke)
|
||
|
{
|
||
|
if (im.ParameterCount == method_count && ret_type == method.ReturnType)
|
||
|
{
|
||
|
|
||
|
for (int i = 0; i < im.ParameterCount; i++)
|
||
|
{
|
||
|
var index = method.IsExtend ? i + 1 : i;
|
||
|
if (im.Parameters[i] != method.Parameters[index] && (!(im is CLRMethod) || (im.Parameters[i].TypeForCLR != method.Parameters[index].TypeForCLR)))
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public Delegate GetConvertor(Type type)
|
||
|
{
|
||
|
if (converters == null)
|
||
|
converters = new Dictionary<System.Type, Delegate>(new ByReferenceKeyComparer<Type>());
|
||
|
Delegate res;
|
||
|
if (converters.TryGetValue(type, out res))
|
||
|
return res;
|
||
|
else
|
||
|
{
|
||
|
res = appdomain.DelegateManager.ConvertToDelegate(type, this);
|
||
|
converters[type] = res;
|
||
|
return res;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsafe StackObject* Minus(StackObject* a, int b)
|
||
|
{
|
||
|
return (StackObject*)((long)a - sizeof(StackObject) * b);
|
||
|
}
|
||
|
|
||
|
public static void ThrowAdapterNotFound(IMethod method)
|
||
|
{
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
sb.Append("Cannot find Delegate Adapter for:");
|
||
|
sb.Append(method.ToString());
|
||
|
string clsName, rName;
|
||
|
bool isByRef;
|
||
|
if (method.ReturnType.Name != "Void" || method.ParameterCount > 0)
|
||
|
{
|
||
|
sb.AppendLine(", Please add following code:");
|
||
|
if (method.ReturnType.Name == "Void")
|
||
|
{
|
||
|
sb.Append("appdomain.DelegateManager.RegisterMethodDelegate<");
|
||
|
bool first = true;
|
||
|
foreach(var i in method.Parameters)
|
||
|
{
|
||
|
if (first)
|
||
|
{
|
||
|
first = false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sb.Append(", ");
|
||
|
}
|
||
|
i.TypeForCLR.GetClassName(out clsName, out rName, out isByRef);
|
||
|
sb.Append(rName);
|
||
|
}
|
||
|
sb.AppendLine(">();");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sb.Append("appdomain.DelegateManager.RegisterFunctionDelegate<");
|
||
|
bool first = true;
|
||
|
foreach (var i in method.Parameters)
|
||
|
{
|
||
|
if (first)
|
||
|
{
|
||
|
first = false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sb.Append(", ");
|
||
|
}
|
||
|
i.TypeForCLR.GetClassName(out clsName, out rName, out isByRef);
|
||
|
sb.Append(rName);
|
||
|
}
|
||
|
if (!first)
|
||
|
sb.Append(", ");
|
||
|
method.ReturnType.TypeForCLR.GetClassName(out clsName, out rName, out isByRef);
|
||
|
sb.Append(rName);
|
||
|
sb.AppendLine(">();");
|
||
|
}
|
||
|
}
|
||
|
throw new KeyNotFoundException(sb.ToString());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsafe interface IDelegateAdapter
|
||
|
{ Type NativeDelegateType { get; }
|
||
|
Delegate Delegate { get; }
|
||
|
IDelegateAdapter Next { get; }
|
||
|
ILTypeInstance Instance { get; }
|
||
|
ILMethod Method { get; }
|
||
|
StackObject* ILInvoke(ILIntepreter intp, StackObject* esp, IList<object> mStack);
|
||
|
IDelegateAdapter Instantiate(Enviorment.AppDomain appdomain, ILTypeInstance instance, ILMethod method);
|
||
|
bool IsClone { get; }
|
||
|
IDelegateAdapter Clone();
|
||
|
Delegate GetConvertor(Type type);
|
||
|
void Combine(IDelegateAdapter adapter);
|
||
|
void Combine(Delegate dele);
|
||
|
void Remove(IDelegateAdapter adapter);
|
||
|
void Remove(Delegate dele);
|
||
|
bool Equals(IDelegateAdapter adapter);
|
||
|
bool Equals(Delegate dele);
|
||
|
}
|
||
|
}
|