示例#1
0
        /// <inheritdoc/>
        public override void GenerateCode(MethodBodyGenerator generator, MethodCompileOption options)
        {
            if (Arguments != null)
            {
                var conversions = ArgumentConversions;
                for (int i = 0; i < Arguments.Count; i++)
                {
                    Arguments[i].GenerateCode(generator);
                    var conversion = conversions[i];
                    if (conversion != null)
                    {
                        generator.EmitConvert(conversion);
                    }
                }
            }
            generator.NewObject(Constructor);

            int length = Expressions.Count;

            if (length > 0)
            {
                var variable = generator.DeclareVariable(Type);
                generator.StoreVariable(variable);
                generator.LoadVariable(variable);
                var conversions = ArrayConversions;
                generator.LoadInt32(length);
                Type type = ElementType;
                generator.NewArray(type);
                for (int i = 0; i < length; i++)
                {
                    generator.Duplicate();
                    generator.LoadInt32(i);
                    var expression = Expressions[i];
                    expression.GenerateCode(generator);
                    if (expression.Type.IsValueType && type.IsValueType == false)
                    {
                        generator.Box(expression.Type);
                    }
                    var convertion = conversions[i];
                    if (convertion != null)
                    {
                        generator.EmitConvert(convertion);
                    }

                    generator.StoreArrayElement(type);
                }
                var m = Type.GetMethod("AddRange", Utils.ReflectionUtils.PublicInstance);
                generator.Call(m);
                generator.LoadVariable(variable);
            }
        }
 public void GenerateGet(Expression target, MethodBodyGenerator generator, MethodCompileOption option = MethodCompileOption.None)
 {
     if (target != null && target.Type.IsValueType)
     {
         generator.Box(target.Type);
     }
     generator.LoadString(Name);
     generator.Call(typeof(IDynamicInvocable).GetInstanceMethod(nameof(IDynamicInvocable.SafeGetValue), typeof(string)));
     // since it is a value type load the address
     if ((option & MethodCompileOption.EmitStartAddress) == MethodCompileOption.EmitStartAddress)
     {
         var temp = generator.DeclareVariable(TypeProvider.AnyType);
         generator.StoreVariable(temp);
         generator.LoadAddressOfVariable(temp);
     }
 }
        System.Delegate Compile(TypeContext context, System.Type returnType, System.Type[] types, ParameterInfo[] parameters, System.Type delType)
        {
            var names = Parameters.Map(para => para.Name).AddFirst("closure");
            // Emit First Argument
            var lamdaVisit = new LamdaVisitor(names);

            Body.Accept(lamdaVisit);
            var parameterTypes = types.AddFirst(typeof(Runtime.Closure));
            var method         = new System.Reflection.Emit.DynamicMethod(Name, returnType, parameterTypes, true);

            var methodGen = new Generators.DynamicMethodGenerator(method, parameters, null)
            {
                SyntaxBody = Body,
                Context    = context
            };

            methodGen.EmitParameterInfo();
            var bodyGen = new MethodBodyGenerator(methodGen, method.GetILGenerator());

            object[] values = new object[lamdaVisit.HoistedLocals.Count];
            if (values.Length > 0)
            {
                int index = 0;
                var field = typeof(Runtime.Closure).GetField("Values");
                foreach (var item in lamdaVisit.HoistedLocals)
                {
                    var value = item.Value;
                    values[index] = value.Accept(ScriptCompiler.Instance);
                    // if binder is null variable or member may not exist
                    if (value.NodeType == ExpressionType.Identifier && ((NameExpression)value).Binder is null)
                    {
                        continue;
                    }
                    var variable = bodyGen.DeclareVariable(value.Type, item.Key);
                    // load closure argument
                    bodyGen.LoadArgument(0);
                    bodyGen.LoadField(field);
                    bodyGen.LoadInt32(index);
                    bodyGen.LoadArrayElement(typeof(object));
                    bodyGen.UnboxObject(value.Type);
                    bodyGen.StoreVariable(variable);
                    index++;
                }
            }
            bodyGen.Compile();
            return(method.CreateDelegate(delType, new Runtime.Closure(values)));
        }
示例#4
0
 public override void GenerateCode(MethodBodyGenerator generator, MethodCompileOption option)
 {
     if (Method.IsAbstract && Method.DeclaringType == typeof(IDynamicInvocable))
     {
         Target.GenerateCode(generator);
         if (Target.Type.IsValueType)
         {
             generator.Box(Target.Type);
         }
     }
     else
     {
         Target.GenerateCode(generator, MethodCompileOption.EmitStartAddress);
     }
     if (Target.NodeType == ExpressionType.MemberAccess)
     {
         MemberExpression target = (MemberExpression)Target;
         if (target.Target.Type.IsValueType)
         {
             switch (target.Target.NodeType)
             {
             case ExpressionType.Indexer:
             case ExpressionType.MemberAccess:
                 var temp = generator.DeclareVariable(target.Target.Type);
                 generator.StoreVariable(temp);
                 generator.LoadAddressOfVariable(temp);
                 break;
             }
         }
     }
     else if (Target.NodeType == ExpressionType.Identifier)
     {
         // if it an identifier expression this might be local member call
         var exp = (NameExpression)Target;
         if (exp.Binder == null && Method.IsStatic == false)
         {
             generator.LoadArgument(0);
         }
     }
     generator.EmitArguments(Arguments, Conversions);
     generator.Call(Method);
     // if current value must not be returned for assigment
     if ((option & MethodCompileOption.Return) == 0 && Type is object && Type != TypeProvider.VoidType)
     {
         generator.Pop();
     }
 }
示例#5
0
 public override void GenerateCode(MethodBodyGenerator generator, MethodCompileOption option)
 {
     if (Left.NodeType == ExpressionType.Identifier)
     {
         var exp    = (NameExpression)Left;
         var binder = exp.Binder;
         // binder is null create new local variable
         if (binder is null)
         {
             exp.Binder = binder = new Binders.VariableBinder(generator.DeclareVariable(Right.Type, exp.Name));
         }
         if ((binder.Attributes & Binders.BindingAttributes.HasThis) != 0)
         {
             generator.LoadArgument(0);
         }
         Right.GenerateCode(generator, Option);
         if (Conversion != null)
         {
             generator.EmitConvert(Conversion);
         }
         binder.GenerateSet(Right, generator, option);
     }
     else if (Left.NodeType == ExpressionType.MemberAccess)
     {
         var exp = (MemberExpression)Left;
         exp.Target.GenerateCode(generator);
         // member assign for dynamic to be Any
         if ((exp.Binder.Attributes & Binders.BindingAttributes.Dynamic) == Binders.BindingAttributes.Dynamic)
         {
             generator.Box(TypeProvider.AnyType);
         }
         Right.GenerateCode(generator, Option);
         if (Conversion != null)
         {
             generator.EmitConvert(Conversion);
         }
         exp.Binder.GenerateSet(Right, generator, option);
     }
     else if (Left.NodeType == ExpressionType.Indexer)
     {
         GenerateIndexer(generator);
     }
 }
        void CallPreFixMember(MethodBodyGenerator generator, IBinder binder, MethodCompileOption option)
        {
            // if no duplicate ex: i++ single line
            if ((option & MethodCompileOption.Dupplicate) == 0)
            {
                binder.GenerateSet(Operand, generator);
                return;
            }
            // ++i where i is member
            // initially operator is called
            var temp = generator.DeclareVariable(binder.Type);

            // store the result to variable
            generator.StoreVariable(temp);
            // then load the variable
            generator.LoadVariable(temp);
            // store the variable result to member
            binder.GenerateSet(Operand, generator);
            // load the temp variable
            generator.LoadVariable(temp);
        }
        /// <inheritdoc/>
        public override void GenerateCode(MethodBodyGenerator generator)
        {
            // Generate code for the start of the statement.
            var statementLocals = new StatementLocals();

            GenerateStartOfStatement(generator, statementLocals);
            if (NodeType == StatementType.Return)
            {
                bool lastStatement = true;
                if (Value != null)
                {
                    var exp = Value.Accept(generator);
                    exp.GenerateCode(generator, Expression.AssignOption);
                    if (generator.SyntaxTree is BlockStatement block)
                    {
                        if (block.Statements.Count > 0)
                        {
                            lastStatement = block.Statements[block.Statements.Count - 1] == this;
                        }
                    }
                    var dest = generator.Method.ReturnType;
                    if (dest is null)
                    {
                        throw new System.NullReferenceException(nameof(System.Reflection.MethodInfo.ReturnType));
                    }
                    // void type no return
                    if (dest != TypeProvider.VoidType)
                    {
                        // todo variable name not used
                        if (generator.ReturnVariable == null)
                        {
                            generator.ReturnVariable = generator.DeclareVariable(dest);
                        }
                        System.Type src = exp.Type;
                        if (!dest.IsAssignableFrom(src))
                        {
                            if (src.TryImplicitConvert(dest, out System.Reflection.MethodInfo method))
                            {
                                if (src.IsValueType && method.GetParameters()[0].ParameterType.IsValueType == false)
                                {
                                    generator.Box(src);
                                }
                                generator.Call(method);
                                src = method.ReturnType;
                            }
                            else
                            {
                                throw new System.Exception(string.Concat("can't cast ", src, " to ", dest));
                            }
                        }
                        if (src.IsValueType && dest.IsValueType == false)
                        {
                            generator.Box(src);
                        }
                        generator.StoreVariable(generator.ReturnVariable);

                        if (generator.ReturnTarget == null)
                        {
                            generator.ReturnTarget = generator.CreateLabel();
                        }
                    }
                }
                //last statement is not a return
                if (!lastStatement)
                {
                    //if iniside try finally block
                    generator.EmitLongJump(generator, generator.ReturnTarget);
                }
            }
            else if (NodeType == StatementType.Throw)
            {
                if (Value == null)
                {
                    throw new System.ArgumentNullException("Value", "throw expression missing argument");
                }
                var exp = Value.Accept(generator);
                exp.GenerateCode(generator, Expression.AssignOption);
                generator.Throw();
            }
            GenerateEndOfStatement(generator, statementLocals);
        }
示例#8
0
 public void GenerateGet(Expression target, MethodBodyGenerator generator, MethodCompileOption option)
 {
     generator.DeclareVariable(key.Type, key.Name);
 }
        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);
            }
        }
        //todo working on scope for better emit
        public System.Delegate Compile(System.Type target, IExpressionVisitor <object> visitor)
        {
            //pass scoped arguments // refer System.Linq.Expression.Compiler folder
            var context = TypeContext.Default;

            System.Type returnType;
            if (ReturnSyntax != null)
            {
                returnType = ReturnSyntax.ResolveType(context);
            }
            else
            {
                returnType = TypeProvider.AnyType;
            }
            var names  = Parameters.Map(para => para.Name).AddFirst("closure");
            int length = Parameters.Count;

            System.Type[] types      = new System.Type[length];
            var           parameters = new ParameterInfo[length];

            for (int i = 0; i < Parameters.Count; i++)
            {
                var         para = Parameters[i];
                System.Type type = para.Type == null ? TypeProvider.AnyType : para.Type.ResolveType(context);
                parameters[i] = new ParameterInfo(para.Name, i + 1, type, para.IsVarArgs);
                types[i]      = type;
            }
            // Emit First Argument
            var lamdaVisit = new LamdaVisitor(names);

            Body.Accept(lamdaVisit);
            var parameterTypes = types.AddFirst(typeof(Closure));
            var method         = new System.Reflection.Emit.DynamicMethod("lambda_method", returnType, parameterTypes, true);

            var methodGen = new Generators.DynamicMethodGenerator(method, parameters, target)
            {
                SyntaxBody = Body,
                Context    = context
            };

            methodGen.EmitParameterInfo();
            var bodyGen = new MethodBodyGenerator(methodGen, method.GetILGenerator());

            object[] values = new object[lamdaVisit.HoistedLocals.Count];
            if (values.Length > 0)
            {
                int index = 0;
                var field = typeof(Closure).GetField("Values");
                foreach (var item in lamdaVisit.HoistedLocals)
                {
                    var value = item.Value;
                    values[index] = value.Accept(visitor);
                    var variable = bodyGen.DeclareVariable(value.Type, item.Key);
                    bodyGen.LoadArgument(0);
                    bodyGen.LoadField(field);
                    bodyGen.LoadInt32(index);
                    bodyGen.LoadArrayElement(typeof(object));
                    bodyGen.UnboxObject(value.Type);
                    bodyGen.StoreVariable(variable);
                    index++;
                }
            }
            bodyGen.Compile();
            var delgateType = DelegateGen.MakeNewDelegate(types, returnType);

            Type = delgateType;
            return(method.CreateDelegate(delgateType, new Runtime.Closure(values)));
        }