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.
1226 lines
36 KiB
1226 lines
36 KiB
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); |
|
} |
|
}
|
|
|