コード例 #1
0
        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);
            }
        }