/// <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); }
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)); } }
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; } }