public override void GenerateCode(MethodBodyGenerator generator)
 {
     foreach (var declaration in DeclarationExpressions)
     {
         declaration.GenerateCode(generator, MethodCompileOption.None);
     }
 }
예제 #2
0
        void IMember.Compile()
        {
            var bodyGen = new MethodBodyGenerator(this, builder.GetILGenerator());

            foreach (FieldGenerator generator in Declaring.Members.Where(mem => mem.MemberType == System.Reflection.MemberTypes.Field && mem.IsStatic == IsStatic))
            {
                if (generator.DefaultValue != null)
                {
                    if (IsStatic == false)
                    {
                        bodyGen.LoadArgument(0);
                    }
                    generator.MethodBody = bodyGen;
                    ((IMember)generator).Compile();
                    generator.DefaultValue.GenerateCode(bodyGen, Expression.AssignOption);
                    bodyGen.StoreField(generator.FieldInfo);
                }
            }
            if (IsStatic == false && Declaring.IsClass)
            {
                // if not call to super or this call
                if (!(SyntaxBody is BlockStatement body && body.Statements.Count > 0 && body.Statements[0] is ExpressionStatement statement && statement.Expression is InvocationExpression exp && (exp.Target.NodeType == ExpressionType.Super || exp.Target.NodeType == ExpressionType.This)))
                {
                    var baseCtor = Declaring.BaseType.GetConstructor(new System.Type[0]);
                    bodyGen.LoadArgument(0);
                    bodyGen.Call(baseCtor);
                }
            }
            bodyGen.Compile();
        }
        public override void GenerateCode(MethodBodyGenerator generator, MethodCompileOption options)
        {
            // Find the result type.
            var resultType = Type;
            var firstType  = Second.Type;
            var secondType = Third.Type;

            First.GenerateCode(generator, MethodCompileOption.Return);
            if (Conversions != null && Conversions.Count > 0)
            {
                generator.EmitConvert(Conversions[0]);
            }
            // Branch if the condition is false.
            var startOfElse = generator.CreateLabel();

            generator.BranchIfFalse(startOfElse);
            Second.GenerateCode(generator, options);
            if (resultType != firstType)
            {
                generator.Call(ExpressionConversion);
            }
            // Branch to the end.
            var end = generator.CreateLabel();

            generator.Branch(end);
            generator.DefineLabelPosition(startOfElse);

            Third.GenerateCode(generator, options);
            if (resultType != secondType)
            {
                generator.Call(ExpressionConversion);
            }
            generator.DefineLabelPosition(end);
        }
 public void GenerateGet(Expression target, MethodBodyGenerator generator, MethodCompileOption option)
 {
     if ((option & MethodCompileOption.EmitStartAddress) == MethodCompileOption.EmitStartAddress && parameter.Type.IsValueType)
     {
         if (generator.Method.IsStatic)
         {
             generator.LoadAddressOfArgument(parameter.Index);
         }
         else
         {
             generator.LoadAddressOfArgument(parameter.Index + 1);
         }
     }
     else
     {
         if (generator.Method.IsStatic)
         {
             generator.LoadArgument(parameter.Index);
         }
         else
         {
             generator.LoadArgument(parameter.Index + 1);
         }
     }
 }
예제 #5
0
        public void GenerateSet(Expression value, MethodBodyGenerator generator, MethodCompileOption option)
        {
            var iLVariable = generator.GetLocalVariable(key.Name);

            if (iLVariable != null)
            {
                generator.LoadVariable(iLVariable);
            }
        }
예제 #6
0
        public void AutoBodyTest()
        {
            var generator = new MethodBodyGenerator();
            var bodyData  = new BodyData()
            {
                IsAuto = true, Body = "ShouldBeIgnored"
            };
            var result = generator.Generate(bodyData);

            Assert.AreEqual(";", result);
        }
예제 #7
0
        /// <inheritdoc/>
        public override void GenerateCode(MethodBodyGenerator generator, MethodCompileOption options)
        {
            //todo unsigned to signed
            switch (Value)
            {
            case sbyte _:
                generator.LoadByte((sbyte)Value);
                generator.NewObject(Utils.ReflectionHelpers.Byte_New);
                break;

            case short _:
                generator.LoadInt16((short)Value);
                generator.NewObject(Utils.ReflectionHelpers.Short_New);
                break;

            case int _:
                generator.LoadInt32((int)Value);
                generator.NewObject(Utils.ReflectionHelpers.Integer_New);
                break;

            case long _:
                generator.LoadInt64((long)Value);
                generator.NewObject(Utils.ReflectionHelpers.Long_New);
                break;

            case float _:
                generator.LoadSingle((float)Value);
                generator.NewObject(Utils.ReflectionHelpers.Float_New);
                break;

            case double _:
                generator.LoadDouble((double)Value);
                generator.NewObject(Utils.ReflectionHelpers.Double_New);
                break;

            case bool value:
                generator.LoadField(value ? Utils.ReflectionHelpers.Bool_True : Utils.ReflectionHelpers.Bool_False);
                break;

            case char _:
                generator.LoadChar((char)Value);
                generator.NewObject(Utils.ReflectionHelpers.Char_New);
                break;

            case string _:
                generator.LoadString(Value.ToString());
                generator.NewObject(Utils.ReflectionHelpers.String_New);
                break;

            case null:
                generator.LoadNull();
                break;
            }
        }
예제 #8
0
        public void NonAutoNullBodyTest()
        {
            var generator = new MethodBodyGenerator();
            var bodyData  = new BodyData()
            {
                IsAuto = false, Body = ""
            };
            var result = generator.Generate(bodyData);

            Assert.AreEqual("{  }", result);
        }
 public void GenerateSet(Expression value, MethodBodyGenerator generator, MethodCompileOption option)
 {
     if (generator.Method.IsStatic)
     {
         generator.StoreArgument(parameter.Index);
     }
     else
     {
         generator.StoreArgument(parameter.Index + 1);
     }
 }
예제 #10
0
 /// <inheritdoc/>
 public override void GenerateCode(MethodBodyGenerator generator, MethodCompileOption option)
 {
     // for static no binder
     if (Binder != null)
     {
         if ((Binder.Attributes & Binders.BindingAttributes.HasThis) != 0)
         {
             generator.LoadArgument(0);
         }
         Binder.GenerateGet(null, generator, option);
     }
 }
예제 #11
0
 public void GenerateGet(Expression target, MethodBodyGenerator generator, MethodCompileOption option)
 {
     if ((option & MethodCompileOption.EmitStartAddress) == MethodCompileOption.EmitStartAddress &&
         variable.Type.IsValueType)
     {
         generator.LoadAddressOfVariable(variable);
     }
     else
     {
         generator.LoadVariable(variable);
     }
 }
예제 #12
0
 public void GenerateGet(Expression target, MethodBodyGenerator generator, MethodCompileOption option)
 {
     if ((option & MethodCompileOption.EmitStartAddress) == MethodCompileOption.EmitStartAddress && property.PropertyType.IsValueType)
     {
         var temp = generator.CreateTemporaryVariable(Type);
         generator.Call(Getter);
         generator.StoreVariable(temp);
         generator.LoadAddressOfVariable(temp);
         return;
     }
     generator.Call(Getter);
 }
예제 #13
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);
            }
        }
예제 #14
0
        public void GenerateSet(Expression value, MethodBodyGenerator generator, MethodCompileOption option)
        {
            if ((option & MethodCompileOption.Dupplicate) == 0)
            {
                generator.Call(Setter);
                return;
            }
            generator.Duplicate();
            var temp = generator.CreateTemporaryVariable(value.Type);

            generator.StoreVariable(temp);
            generator.Call(Setter);
            generator.LoadVariable(temp);
        }
예제 #15
0
 public override void GenerateCode(MethodBodyGenerator generator, MethodCompileOption options)
 {
     if (Target.Type.IsValueType)
     {
         options |= MethodCompileOption.EmitStartAddress;
     }
     Target.GenerateCode(generator, options);
     Arguments.ForEach((arg, index) =>
     {
         arg.GenerateCode(generator);
         generator.EmitConvert(Conversions[index]);
     });
     // todo indexer parmas argument convert
     generator.Call(Getter);
 }
 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)));
        }
예제 #18
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();
     }
 }
예제 #19
0
        ///<inheritdoc/>
        public override void GenerateCode(MethodBodyGenerator generator)
        {
            var statementLocals = new StatementLocals()
            {
                NonDefaultSourceSpanBehavior = true
            };

            GenerateStartOfStatement(generator, statementLocals);
            if (Statements.Count == 0)
            {
                generator.NoOperation();
            }
            for (int index = 0; index < Statements.Count; index++)
            {
                Statements[index].GenerateCode(generator);
            }
            GenerateEndOfStatement(generator, statementLocals);
        }
예제 #20
0
        public static void MakeObjectArray(MethodBodyGenerator generator, ICollection <Expression> expressions)
        {
            int i = 0;

            generator.LoadInt32(expressions.Count);
            generator.NewArray(typeof(object));
            foreach (var expression in expressions)
            {
                generator.Duplicate();
                generator.LoadInt32(i++);
                expression.Accept(generator).GenerateCode(generator);
                if (expression.Type.IsValueType)
                {
                    generator.Box(expression.Type);
                }
                generator.StoreArrayElement(typeof(object));
            }
        }
예제 #21
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);
     }
 }
 public override void GenerateCode(MethodBodyGenerator generator, MethodCompileOption option)
 {
     if (Binder != null)
     {
         if (Target.Type.IsValueType && (Binder.Attributes & Binders.BindingAttributes.Dynamic) == 0)
         {
             option = MethodCompileOption.EmitStartAddress;
         }
         else
         {
             option = 0;
         }
         Target.GenerateCode(generator, option);
         Binder.GenerateGet(Target, generator);
     }
     else
     {
         Target.GenerateCode(generator, option);
     }
 }
 public void GenerateSet(Expression right, MethodBodyGenerator generator, MethodCompileOption option = MethodCompileOption.None)
 {
     // first parameter to be Any
     if (right.Type != TypeProvider.AnyType)
     {
         if (right.Type.IsValueType)
         {
             generator.Box(right.Type);
         }
         generator.CallStatic(ReflectionHelpers.ImplicitAny);
     }
     generator.LoadString(Name);
     generator.LoadToken(right.Type);
     generator.Call((Func <RuntimeTypeHandle, Type>)Type.GetTypeFromHandle);
     generator.Call(typeof(IDynamicInvocable).GetInstanceMethod(nameof(IDynamicInvocable.SafeSetValue), TypeProvider.AnyType, typeof(string), typeof(Type)));
     if ((option & MethodCompileOption.Return) == 0)
     {
         generator.Pop();
         return;
     }
 }
예제 #24
0
 public override void GenerateCode(MethodBodyGenerator generator, MethodCompileOption options)
 {
     if (generator.Method is Generators.DynamicMethodGenerator)
     {
         // for annonymous type
         // if this is used in anonymous function or objects
         var variable = generator.GetLocalVariable("__value");
         if (variable.Type.IsValueType && (options & MethodCompileOption.EmitStartAddress) == MethodCompileOption.EmitStartAddress)
         {
             generator.LoadAddressOfVariable(variable);
         }
         else
         {
             generator.LoadVariable(variable);
         }
     }
     else
     {
         generator.LoadArgument(0);
     }
 }
예제 #25
0
        public void GenerateGet(Expression target, MethodBodyGenerator generator, MethodCompileOption option)
        {
            var field = this.field;

            if (field.FieldType == null)
            {
                throw new InvalidOperationException(string.Concat("Use of undeclared field ", field));
            }
            if (field is Generators.FieldGenerator)
            {
                field = ((Generators.FieldGenerator)field).FieldInfo;
            }
            if ((option & MethodCompileOption.EmitStartAddress) == MethodCompileOption.EmitStartAddress && field.FieldType.IsValueType)
            {
                generator.LoadFieldAddress(field);
            }
            else
            {
                generator.LoadField(field);
            }
        }
예제 #26
0
        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);
        }
 public override void GenerateCode(MethodBodyGenerator generator, MethodCompileOption options)
 {
     if (Method != null)
     {
         var conversions = Conversions;
         Left.GenerateCode(generator, options);
         var first = conversions[0];
         if (first != null)
         {
             generator.EmitConvert(first);
         }
         Right.GenerateCode(generator, options);
         var second = conversions[1];
         if (second != null)
         {
             generator.EmitConvert(second);
         }
         generator.Call(Method);
         return;
     }
     throw new InvalidOperationException("Operator method missing");
 }
예제 #28
0
        public void GenerateIndexer(MethodBodyGenerator generator)
        {
            var exp         = (IndexExpression)Left;
            var conversions = exp.Conversions;
            var arguments   = exp.Arguments;

            exp.Target.GenerateCode(generator, MethodCompileOption.EmitStartAddress);
            var argLength = arguments.Count;

            for (int index = 0; index < argLength; index++)
            {
                var arg  = arguments[index];
                var conv = conversions[index];
                if (conv != null)
                {
                    if (conv.ConversionType == ConversionType.Normal)
                    {
                        arg.GenerateCode(generator, AssignOption);
                        generator.EmitConvert(conv);
                    }
                    else if (conv.ConversionType == ConversionType.ParamArray)
                    {
                        var args = new Expression[arguments.Count - index];
                        arguments.CopyTo(args, conv.Index);
                        generator.EmitConvert((ParamArrayConversion)conv, args);
                    }
                }
                else
                {
                    arg.GenerateCode(generator, AssignOption);
                }
            }
            Right.GenerateCode(generator, MethodCompileOption.Dupplicate);
            // value convert if any
            generator.EmitConvert(conversions[argLength]);
            generator.Call(exp.Setter);
        }
예제 #29
0
        public void GenerateSet(Expression value, MethodBodyGenerator generator, MethodCompileOption option)
        {
            var field = this.field;

            if (field.IsInitOnly && !(generator.Method is ConstructorInfo))
            {
                throw new FieldAccessException("A readonly field cannot be assigned to (except in a constructor of the class in which the field is defined or a variable initializer))");
            }
            if (field is Generators.FieldGenerator)
            {
                field = ((Generators.FieldGenerator)field).FieldInfo;
            }
            if ((option & MethodCompileOption.Dupplicate) == 0)
            {
                generator.StoreField(field);
                return;
            }
            generator.Duplicate();
            var temp = generator.CreateTemporaryVariable(value.Type);

            generator.StoreVariable(temp);
            generator.StoreField(field);
            generator.LoadVariable(temp);
        }
 public void GenerateSet(Expression value, MethodBodyGenerator generator, MethodCompileOption option = MethodCompileOption.None)
 {
     throw new NotImplementedException();
 }