private void CreateFunction(Generators.TypeGenerator generator, System.Type returnType, ParameterInfo[] parameters) { var parameterTypes = parameters.Map(p => p.Type); //todo override toString and others var name = string.Concat(char.ToUpper(Name.First()), Name.Substring(1)); System.Reflection.MethodAttributes attributes = GetAttributes(); if ((attributes & System.Reflection.MethodAttributes.Virtual) == System.Reflection.MethodAttributes.Virtual) { generator.CheckImplementMethod(Name, parameterTypes, ref name, ref returnType, ref attributes); } // create method var method = generator.Builder.DefineMethod(name, attributes, returnType, parameterTypes); //set runtime method name Generators.MethodGenerator methodGen = new Generators.MethodGenerator(method, parameters, generator) { SyntaxBody = Body }; methodGen.SetCustomAttribute(typeof(Runtime.RegisterAttribute), Utils.ReflectionHelpers.Register_Attr_Ctor, new object[] { Name }); generator.Add(methodGen); }
public override void GenerateCode(MethodBodyGenerator generator, MethodCompileOption option) { var target = generator.Method.DeclaringType; IExpressionVisitor <object> visitor = ScriptCompiler.Instance; //pass scoped arguments // refer System.Linq.Expression.Compiler folder var names = Parameters.Map(para => para.Name); // Emit First Argument var lamdaVisit = new LamdaVisitor(names); Body.Accept(lamdaVisit); LamdaGen lamdaGen; if (generator.Method.DeclaringType is Generators.TypeGenerator typeGen) { lamdaGen = typeGen.DefineAnonymousMethod(Types, ReturnType); } else { lamdaGen = AssemblyGen.DynamicAssembly.DefineAnonymousMethod(Types, ReturnType); } var methodGen = new Generators.MethodGenerator(lamdaGen.Method, ParameterInfos, lamdaGen.Type) { SyntaxBody = Body, Context = generator.Context }; methodGen.EmitParameterInfo(); var bodyGen = new MethodBodyGenerator(methodGen, lamdaGen.Method.GetILGenerator()); var values = lamdaVisit.HoistedLocals.Values; // new object[] {} var valVar = generator.DeclareVariable(LamdaGen.ObjectArray); ArrayListExpression.MakeObjectArray(generator, values); generator.StoreVariable(valVar); if (values.Count > 0) { int index = 0; var field = lamdaGen.Values; foreach (var item in lamdaVisit.HoistedLocals) { var value = item.Value; var variable = bodyGen.DeclareVariable(value.Type, item.Key); bodyGen.LoadArgument(0); bodyGen.LoadField(field); bodyGen.LoadInt32(index); bodyGen.LoadArrayElement(TypeProvider.ObjectType); bodyGen.UnboxObject(value.Type); bodyGen.StoreVariable(variable); index++; } } bodyGen.Compile(); var type = lamdaGen.CreateType(); generator.LoadVariable(valVar); if (generator.Method is Generators.DynamicMethodGenerator) { generator.NewObject(type.GetConstructor(LamdaGen.CtorSignature)); generator.LoadFunction(type.GetMethod(ReflectionUtils.InvokeMethod, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), Type); } else { generator.NewObject(lamdaGen.Constructor); generator.LoadFunction(lamdaGen.Method, Type); } }