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 && property.PropertyType.IsValueType) { var temp = generator.CreateTemporaryVariable(Type); generator.Call(Getter); generator.StoreVariable(temp); generator.LoadAddressOfVariable(temp); return; } generator.Call(Getter); }
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); }
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 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; } }
/// <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 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); } }
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(); } }
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"); }
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); }
/// <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); }