private Dictionary <string, CILantroType> RegisterCustomTypes(CILProgram program) { var result = new Dictionary <string, CILantroType>(); var runtimeTypeFactory = new RuntimeTypeFactory(Program.Assemblies.SingleOrDefault(), program.Modules.SingleOrDefault()); foreach (var cilClass in program.Classes) { Type runtimeType = null; var customType = new CILantroType(cilClass, this); if (RuntimeTypeHelper.GetRuntimeType(cilClass.Extends) == typeof(Enum)) { runtimeType = runtimeTypeFactory.RegisterEnumType(cilClass); } else if (RuntimeTypeHelper.GetRuntimeType(cilClass.Extends) != null) { runtimeType = runtimeTypeFactory.RegisterType(cilClass, this, customType); } cilClass.RuntimeType = runtimeType; customType._runtimeType = runtimeType; result.Add(cilClass.ClassName.UniqueName, customType); } return(result); }
public Type RegisterType(CILClass cilClass, CILProgramInstance programInstance, CILantroType cilantroType) { var parentTypeAssembly = Assembly.Load(cilClass.Extends.AssemblyName); var parentType = parentTypeAssembly.GetType(cilClass.Extends.ClassName); var typeBuilder = _moduleBuilder.DefineType(cilClass.ClassName.ClassName, TypeAttributes.Class, parentType); foreach (var method in parentType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { if (method.IsAbstract) { //typeBuilder.DefineMethodOverride(method, method); var methodBuilder = typeBuilder.DefineMethod(method.Name, (method.Attributes & (~MethodAttributes.Abstract)), method.ReturnType, method.GetParameters().Select(p => p.ParameterType).ToArray()); var msil = methodBuilder.GetILGenerator(); msil.ThrowException(typeof(NotImplementedException)); typeBuilder.DefineMethodOverride(methodBuilder, method); //var cilMethods = cilClass.Methods.Select(m => new CILantroMethodInfo(m, programInstance, typeBuilder)).ToList(); //var cilMethod = cilMethods.SingleOrDefault(m => m.Name == method.Name && CILantroType.CompareArgumentTypes(m.GetParameters().Select(p => p.ParameterType).ToArray(), method.GetParameters().Select(p => p.ParameterType).ToArray())); //typeBuilder.DefineMethodOverride(cilMethod, method); } } var type = typeBuilder.CreateType(); return(type); }
public override CILInstructionInstance Execute(CILInstructionInstance instructionInstance, CILProgramState state, CILProgramInstance programInstance, Stack <CILInstructionInstance> callStack) { var reflectedType = TypeSpecification.GetTypeSpecified(programInstance); var reflectedMethod = (MethodBase)reflectedType.GetMethod(MethodName, GetMethodArgumentRuntimeTypes(programInstance).ToArray()); if (reflectedMethod == null && MethodName.Equals(".ctor") && ParentMethod.IsConstructor) { return(instructionInstance.GetNextInstructionInstance()); } var methodArguments = new List <object>(); for (int i = 0; i < MethodArgumentTypes.Count; i++) { var argumentType = GetMethodArgumentRuntimeTypes(programInstance)[MethodArgumentTypes.Count - i - 1]; var argument = state.Stack.Pop(); var methodArgument = ConvertHelper.ConvertIfPossible(argument, argumentType); methodArguments.Add(methodArgument); } methodArguments.Reverse(); object methodObject = null; if (CallConvention.Instance) { methodObject = state.Stack.Pop(); if (methodObject is Guid) { var objectAddress = (Guid)methodObject; methodObject = ParentMethod.GetLocalByAddress(objectAddress); } } var methodObjectToCall = methodObject; if (methodObjectToCall is CILClassInstance) { methodObjectToCall = (methodObjectToCall as CILClassInstance).BaseInstance; } if (methodObject is CILClassInstance) { var cilClass = (methodObject as CILClassInstance)._cilClass; var cilMethod = cilClass.Methods.SingleOrDefault(m => m.MethodName == this.MethodName && CILantroType.CompareArgumentTypes(m.ArgumentTypes.Select(at => at.GetRuntimeType(programInstance)).ToArray(), this.GetMethodArgumentRuntimeTypes(programInstance).ToArray())); while (cilClass != null && cilMethod == null) { cilClass = cilClass.ExtendsClass; if (cilClass != null) { cilMethod = cilClass.Methods.SingleOrDefault(m => m.MethodName == this.MethodName && CILantroType.CompareArgumentTypes(m.ArgumentTypes.Select(at => at.GetRuntimeType(programInstance)).ToArray(), this.GetMethodArgumentRuntimeTypes(programInstance).ToArray())); } } if (cilMethod != null) { var newMethodInfo = new CILantroMethodInfo(cilMethod, programInstance, cilMethod.ReturnType.GetRuntimeType(programInstance)); reflectedMethod = newMethodInfo; } } if (reflectedMethod is CILantroMethodInfo) { callStack.Push(instructionInstance.GetNextInstructionInstance()); var cilantroMethodInfo = reflectedMethod as CILantroMethodInfo; CILMethod methodToCall = null; object obj = methodObject; //object obj = null; if (CallConvention.Instance) { //obj = state.Stack.Pop(); var cilClassInstance = obj as CILClassInstance; var cilClass = cilClassInstance._cilClass; while (cilClass != null) { var matchingMethod = cilClass.Methods.FirstOrDefault(m => m.MethodName.Equals(MethodName) && CILantroType.CompareArgumentTypes(GetMethodArgumentRuntimeTypes(programInstance).ToArray(), m.ArgumentTypes.Select(ct => ct.GetRuntimeType(programInstance)).ToArray())); if (matchingMethod != null) { methodToCall = matchingMethod; break; } cilClass = programInstance.Program.Classes.FirstOrDefault(c => c.ClassName.UniqueName == cilClass.Extends.UniqueName); } } if (methodToCall == null) { methodToCall = cilantroMethodInfo.Method; } return(methodToCall.CreateInstance(obj, methodArguments.ToArray()).GetFirstInstructionInstance()); } var methodResult = reflectedMethod.Invoke(methodObjectToCall, methodArguments.ToArray()); if (MethodReturnType.GetRuntimeType(programInstance) != typeof(void)) { state.Stack.Push(methodResult); } return(instructionInstance.GetNextInstructionInstance()); }