protected GrabMethod ( MethodInfo Original, TypeBuilder On ) : MethodInfo | ||
Original | MethodInfo | |
On | TypeBuilder | |
return | MethodInfo |
protected MethodInfo GrabMethod(MethodInfo Original, TypeBuilder On)
{
if(Original == null) return null;
if(MethodsDone.ContainsKey(Original))
return MethodsDone[Original];
if(!Sources.Contains(Original.Module))
return MethodReplaceGenerics(Original);
if(On == null)
On = GrabType(Original.DeclaringType) as TypeBuilder;
if((Original.Attributes & MethodAttributes.PinvokeImpl) == MethodAttributes.PinvokeImpl)
return GrabPInvokeImpl(Original, On);
Type ReturnType = GrabType(Original.ReturnType);
Type[] Parameters = ParameterTypes(Original);
if(MethodsDone.ContainsKey(Original))
return MethodsDone[Original];
MethodBuilder Builder = On.DefineMethod(Original.Name, Original.Attributes, ReturnType, Parameters);
MethodsDone.Add(Original, Builder);
// Explicit interface implementations require specifying which method is being overridden.
if(Original.IsFinal)
{
if(Original.Name.Contains("."))
{
MethodInfo Overriding = FindBaseMethod(Original, Original.DeclaringType);
if(Overriding != null)
On.DefineMethodOverride(Builder, Overriding);
}
else
{
// Crawl among the interfaces attempting to guess the method that is being overridden.
foreach(Type T in Original.DeclaringType.GetInterfaces())
{
foreach(MethodInfo M in T.GetMethods())
{
if(M.IsAbstract && M.Name == Original.Name)
{
On.DefineMethodOverride(Builder, M);
goto foundoverride; // For lack of "break 2" statement.
}
}
}
}
}
foundoverride:
Builder.SetImplementationFlags(Original.GetMethodImplementationFlags());
CopyMethodBody(Original, Builder);
return Builder;
}
ILMirror::GrabMethod ( MethodInfo Original ) : MethodInfo |
public MethodWriter(TypeBuilder Parent, CodeMemberMethod Member, MethodCollection Lookup, ILMirror Mirror) { Loops = new Stack <LoopMetadata>(); this.Member = Member; this.Lookup = Lookup; this.Mirror = Mirror; if (Member is CodeEntryPointMethod) { Method = Parent.DefineMethod("Main", MethodAttributes.Private | MethodAttributes.Static, typeof(void), null); IsEntryPoint = true; } else { Method = Parent.DefineMethod(Member.Name, MethodAttributes.Public | MethodAttributes.Static, typeof(object), new[] { typeof(object[]) }); } Generator = Method.GetILGenerator(); ForceString = typeof(Script).GetMethod("ForceString"); ForceDecimal = typeof(Script).GetMethod("ForceDecimal"); ForceLong = typeof(Script).GetMethod("ForceLong"); ForceInt = typeof(Script).GetMethod("ForceInt"); ForceBool = typeof(Script).GetMethod("ForceBool"); Locals = new Dictionary <string, LocalBuilder>(); Labels = new Dictionary <string, LabelMetadata>(); Type Variables = typeof(Script.Variables); if (IsEntryPoint) { GenerateEntryPointHeader(Generator); } SetVariable = typeof(Script.Variables).GetMethod("SetVariable"); GetVariable = typeof(Script.Variables).GetMethod("GetVariable"); MethodInfo GetVars = typeof(Script).GetMethod("get_Vars"); if (Mirror != null) { ForceString = Mirror.GrabMethod(ForceString); ForceDecimal = Mirror.GrabMethod(ForceDecimal); ForceLong = Mirror.GrabMethod(ForceLong); ForceInt = Mirror.GrabMethod(ForceInt); ForceBool = Mirror.GrabMethod(ForceBool); SetVariable = Mirror.GrabMethod(SetVariable); GetVariable = Mirror.GrabMethod(GetVariable); Variables = Mirror.GrabType(Variables); GetVars = Mirror.GrabMethod(GetVars); } VarsProperty = Generator.DeclareLocal(Variables); Generator.Emit(OpCodes.Call, GetVars); Generator.Emit(OpCodes.Stloc, VarsProperty); }