示例#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 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);
        }
示例#3
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));
            }
        }
示例#4
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 override void GenerateCode(MethodBodyGenerator generator, MethodCompileOption option)
        {
            if (NodeType == ExpressionType.Parenthesized)
            {
                Operand.GenerateCode(generator, option);
                return;
            }
            var     operand = Operand;
            IBinder binder  = null;

            if (operand.NodeType == ExpressionType.Identifier)
            {
                //todo only for get; set; member
                //i++ or Member++
                binder = ((NameExpression)operand).Binder;
            }
            else if (operand.NodeType == ExpressionType.MemberAccess)
            {
                binder = ((MemberExpression)operand).Binder;
            }
            // todo: Conversion if value is short, byte lower data type

            switch (NodeType)
            {
            case ExpressionType.PostfixMinusMinus:
            case ExpressionType.PostfixPlusPlus:
                if (binder == null)
                {
                    throw new NullReferenceException(nameof(binder));
                }
                if ((binder.Attributes & BindingAttributes.HasThis) != 0)
                {
                    generator.LoadArgument(0);
                }
                operand.GenerateCode(generator, MethodCompileOption.Dupplicate);
                if ((binder.Attributes & BindingAttributes.Member) != 0)
                {
                    CallPostFixMember(generator, binder, option);
                    return;
                }
                if ((option & MethodCompileOption.Dupplicate) != 0)
                {
                    generator.Duplicate();
                }
                // call the operator
                generator.CallStatic(Method);
                // update value
                binder.GenerateSet(operand, generator);
                break;

            case ExpressionType.PrefixMinusMinus:
            case ExpressionType.PrefixPlusPlus:
                if (binder == null)
                {
                    throw new NullReferenceException(nameof(binder));
                }
                if ((binder.Attributes & BindingAttributes.HasThis) != 0)
                {
                    generator.LoadArgument(0);
                }
                operand.GenerateCode(generator, MethodCompileOption.Dupplicate);
                // call the operator
                generator.CallStatic(Method);
                if ((binder.Attributes & BindingAttributes.Member) != 0)
                {
                    CallPreFixMember(generator, binder, option);
                    return;
                }
                if ((option & MethodCompileOption.Dupplicate) != 0)
                {
                    generator.Duplicate();
                }
                // update value
                binder.GenerateSet(Operand, generator);
                break;

            default:
                // call the operator
                operand.GenerateCode(generator, AssignOption);
                generator.CallStatic(Method);
                break;
            }
        }