public override void Compile(EmitCompilerContext context, EmitIl il) { foreach (var statement in Statements) { statement.Compile(context, il); } }
public override void Compile(EmitCompilerContext context, EmitIl il) { Condition.Compile(context, il); var ifNotTrue = il.DefineLabel(); il.Emit(EmitOpCodes.Brfalse, ifNotTrue); Statement.Compile(context, il); var statementReturned = il.Instructions.Last().OpCode == EmitOpCodes.Ret; if (Else != null) { EmitLabel end = null; if (!statementReturned) { end = il.DefineLabel(); il.Emit(EmitOpCodes.Br, end); } il.MarkLabel(ifNotTrue); Else.Compile(context, il); if (!statementReturned) { il.MarkLabel(end); il.Emit(EmitOpCodes.Nop); } } else { il.MarkLabel(ifNotTrue); } }
public override void Compile(EmitCompilerContext context, EmitIl il) { var arrayType = GetExpressionType(); if (Lengths.Count == 1) { il.Emit(EmitOpCodes.Ldc_I4, Lengths[0]); il.Emit(EmitOpCodes.Newarr, Type); for (var i = 0; i < Initializer.Length; i++) { var element = (EmitExpression)Initializer[i]; il.Emit(EmitOpCodes.Dup); il.Emit(EmitOpCodes.Ldc_I4, i); element.Compile(context, il); il.Emit(EmitOpCodes.Stelem, Type); } } else { var constructor = arrayType.Members.OfType <EmitConstructor>().Single(x => x.Parameters.Count() == Rank); var setter = arrayType.Members.OfType <EmitMethod>().Single(x => x.Name == "Set"); foreach (var length in Lengths) { il.Emit(EmitOpCodes.Ldc_I4, length); } il.Emit(EmitOpCodes.Newobj, constructor); var indices = new int[Lengths.Count]; Action <int, IEmitArrayElement> recurse = null; recurse = (level, element) => { if (level == Rank - 1) { var expression = (EmitExpression)element; il.Emit(EmitOpCodes.Dup); foreach (var index in indices) { il.Emit(EmitOpCodes.Ldc_I4, index); } expression.Compile(context, il); il.Emit(EmitOpCodes.Call, setter); } else { for (var i = 0; i < element.Length; i++) { indices[level + 1] = i; var current = element[i]; recurse(level + 1, current); } } }; for (var i = 0; i < Initializer.Length; i++) { var element = Initializer[i]; indices[0] = i; recurse(0, element); } } }
public override void Compile(EmitCompilerContext context, EmitIl il) { switch (Operator) { case EmitBinaryOperator.Assign: ((IEmitReferenceExpression)Left).CompileAssignment(context, il, () => Right.Compile(context, il)); break; case EmitBinaryOperator.BooleanAnd: Left.Compile(context, il); il.Emit(EmitOpCodes.Dup); var andEnd = il.DefineLabel(); il.Emit(EmitOpCodes.Brfalse, andEnd); il.Emit(EmitOpCodes.Pop); Right.Compile(context, il); il.MarkLabel(andEnd); break; case EmitBinaryOperator.BooleanOr: Left.Compile(context, il); il.Emit(EmitOpCodes.Dup); var orEnd = il.DefineLabel(); il.Emit(EmitOpCodes.Brtrue, orEnd); il.Emit(EmitOpCodes.Pop); Right.Compile(context, il); il.MarkLabel(orEnd); break; default: var instruction = GetOpCode(); var isInverted = IsOperatorInverse(); var isAssignment = IsOperatorAssignment(); Left.Compile(context, il); Right.Compile(context, il); il.Emit(instruction); if (isInverted) { il.Emit(EmitOpCodes.Ldc_I4_0); il.Emit(EmitOpCodes.Ceq); } if (isAssignment) { var local = il.DeclareLocal(typeof(bool)); il.Emit(EmitOpCodes.Stloc, local); ((IEmitReferenceExpression)Left).CompileAssignment(context, il, () => il.Emit(EmitOpCodes.Ldloc, local)); } break; } }
public override void Compile(EmitCompilerContext context, EmitIl il) { if (Value == null) { il.Emit(EmitOpCodes.Ldnull); } else if (Value is int) { il.Emit(EmitOpCodes.Ldc_I4, (int)Value); } else if (Value is long) { il.Emit(EmitOpCodes.Ldc_I8, (long)Value); } else if (Value is float) { il.Emit(EmitOpCodes.Ldc_R4, (float)Value); } else if (Value is double) { il.Emit(EmitOpCodes.Ldc_R8, (double)Value); } else if (Value is bool) { il.Emit(EmitOpCodes.Ldc_I4, (bool)Value ? 1 : 0); } else if (Value is string) { il.Emit(EmitOpCodes.Ldstr, (string)Value); } else { throw new Exception(); } }
public override void Compile(EmitCompilerContext context, EmitIl il) { foreach (var variable in Variables) { var local = il.DeclareLocal(variable.Type); variable.SetData(context, local); } }
public void CompileAssignment(EmitCompilerContext context, EmitIl il, Action compileValue) { var local = Variable.GetData(context); compileValue(); il.Emit(EmitOpCodes.Dup); // We want to leave the assigned value on the stack, since assignment is an expression il.Emit(EmitOpCodes.Stloc, local); }
public override void Compile(EmitCompilerContext context, EmitIl il) { var arrayType = GetExpressionType(); if (Lengths.Count == 1) { il.Emit(EmitOpCodes.Ldc_I4, Lengths[0]); il.Emit(EmitOpCodes.Newarr, Type); for (var i = 0; i < Initializer.Length; i++) { var element = (EmitExpression)Initializer[i]; il.Emit(EmitOpCodes.Dup); il.Emit(EmitOpCodes.Ldc_I4, i); element.Compile(context, il); il.Emit(EmitOpCodes.Stelem, Type); } } else { var constructor = arrayType.Members.OfType<EmitConstructor>().Single(x => x.Parameters.Count() == Rank); var setter = arrayType.Members.OfType<EmitMethod>().Single(x => x.Name == "Set"); foreach (var length in Lengths) il.Emit(EmitOpCodes.Ldc_I4, length); il.Emit(EmitOpCodes.Newobj, constructor); var indices = new int[Lengths.Count]; Action<int, IEmitArrayElement> recurse = null; recurse = (level, element) => { if (level == Rank - 1) { var expression = (EmitExpression)element; il.Emit(EmitOpCodes.Dup); foreach (var index in indices) { il.Emit(EmitOpCodes.Ldc_I4, index); } expression.Compile(context, il); il.Emit(EmitOpCodes.Call, setter); } else { for (var i = 0; i < element.Length; i++) { indices[level + 1] = i; var current = element[i]; recurse(level + 1, current); } } }; for (var i = 0; i < Initializer.Length; i++) { var element = Initializer[i]; indices[0] = i; recurse(0, element); } } }
public override void Compile(EmitCompilerContext context, EmitIl il) { if (Arguments.Count != Method.Parameters.Count()) throw new Exception($"Incorrect number of arguments passed to method {Method}"); Target?.Compile(context, il); foreach (var argument in Arguments) argument.Compile(context, il); var opCode = Method.IsVirtual || Method.DeclaringType.IsInterface ? (IEmitOpCodeMethod)EmitOpCodes.Callvirt : EmitOpCodes.Call; il.Emit(opCode, Method); }
public override void Compile(EmitCompilerContext context, EmitIl il) { if (Arguments.Count != Method.Parameters.Count()) { throw new Exception($"Incorrect number of arguments passed to method {Method}"); } Target?.Compile(context, il); foreach (var argument in Arguments) { argument.Compile(context, il); } var opCode = Method.IsVirtual || Method.DeclaringType.IsInterface ? (IEmitOpCodeMethod)EmitOpCodes.Callvirt : EmitOpCodes.Call; il.Emit(opCode, Method); }
public override void Compile(EmitCompilerContext context, EmitIl il) { if (Lengths.Count == 1) { Lengths[0].Compile(context, il); il.Emit(EmitOpCodes.Newarr, Type); } else { var arrayType = GetExpressionType(); var constructor = arrayType.Members.OfType<EmitConstructor>().Single(x => x.Parameters.Count() == Lengths.Count); foreach (var length in Lengths) { length.Compile(context, il); } il.Emit(EmitOpCodes.Newobj, constructor); } }
public override void Compile(EmitCompilerContext context, EmitIl il) { if (Lengths.Count == 1) { Lengths[0].Compile(context, il); il.Emit(EmitOpCodes.Newarr, Type); } else { var arrayType = GetExpressionType(); var constructor = arrayType.Members.OfType <EmitConstructor>().Single(x => x.Parameters.Count() == Lengths.Count); foreach (var length in Lengths) { length.Compile(context, il); } il.Emit(EmitOpCodes.Newobj, constructor); } }
public override void Compile(EmitCompilerContext context, EmitIl il) { // Special handling for value types without a constructor if (Constructor == null) { var local = il.DeclareLocal(Type); il.Emit(EmitOpCodes.Ldloca, local); il.Emit(EmitOpCodes.Initobj, Type); il.Emit(EmitOpCodes.Ldloc, local); return; } foreach (var argument in Arguments) { argument.Compile(context, il); } il.Emit(EmitOpCodes.Newobj, Constructor); }
public override void Compile(EmitCompilerContext context, EmitIl il) { if (Value == null) il.Emit(EmitOpCodes.Ldnull); else if (Value is int) il.Emit(EmitOpCodes.Ldc_I4, (int)Value); else if (Value is long) il.Emit(EmitOpCodes.Ldc_I8, (long)Value); else if (Value is float) il.Emit(EmitOpCodes.Ldc_R4, (float)Value); else if (Value is double) il.Emit(EmitOpCodes.Ldc_R8, (double)Value); else if (Value is bool) il.Emit(EmitOpCodes.Ldc_I4, (bool)Value ? 1 : 0); else if (Value is string) il.Emit(EmitOpCodes.Ldstr, (string)Value); else throw new Exception(); }
public override void Compile(EmitCompilerContext context, EmitIl il) { var item = il.DeclareLocal(Item.Type); Item.SetData(context, item); EmitType genericEnumerableType = typeof(IEnumerable <>); var enumerableType = genericEnumerableType.MakeGenericType(Item.Type); var getEnumeratorMethod = enumerableType.Members.OfType <EmitMethod>().Single(x => x.Name == nameof(IEnumerable <object> .GetEnumerator)); EmitType genericEnumeratorType = typeof(IEnumerator <>); var enumeratorType = genericEnumeratorType.MakeGenericType(Item.Type); var moveNextMethod = enumerableType.Members.OfType <EmitMethod>().Single(x => x.Name == nameof(IEnumerator <object> .MoveNext)); var getCurrentMethod = enumerableType.Members.OfType <EmitProperty>().Single(x => x.Name == nameof(IEnumerator <object> .Current)).GetMethod; var enumerator = il.DeclareLocal(enumeratorType); Collection.Compile(context, il); il.Emit(EmitOpCodes.Callvirt, getEnumeratorMethod); il.Emit(EmitOpCodes.Stloc, enumerator); var topOfLoop = il.DefineLabel(); var end = il.DefineLabel(); il.MarkLabel(topOfLoop); il.Emit(EmitOpCodes.Ldloc, enumerator); il.Emit(EmitOpCodes.Callvirt, moveNextMethod); il.Emit(EmitOpCodes.Brfalse, end); il.Emit(EmitOpCodes.Ldloc, enumerator); il.Emit(EmitOpCodes.Callvirt, getCurrentMethod); il.Emit(EmitOpCodes.Stloc, item); Statement.Compile(context, il); il.Emit(EmitOpCodes.Br, topOfLoop); il.MarkLabel(end); il.Emit(EmitOpCodes.Nop); }
public override void Compile(EmitCompilerContext context, EmitIl il) { var item = il.DeclareLocal(Item.Type); Item.SetData(context, item); EmitType genericEnumerableType = typeof(IEnumerable<>); var enumerableType = genericEnumerableType.MakeGenericType(Item.Type); var getEnumeratorMethod = enumerableType.Members.OfType<EmitMethod>().Single(x => x.Name == nameof(IEnumerable<object>.GetEnumerator)); EmitType genericEnumeratorType = typeof(IEnumerator<>); var enumeratorType = genericEnumeratorType.MakeGenericType(Item.Type); var moveNextMethod = enumerableType.Members.OfType<EmitMethod>().Single(x => x.Name == nameof(IEnumerator<object>.MoveNext)); var getCurrentMethod = enumerableType.Members.OfType<EmitProperty>().Single(x => x.Name == nameof(IEnumerator<object>.Current)).GetMethod; var enumerator = il.DeclareLocal(enumeratorType); Collection.Compile(context, il); il.Emit(EmitOpCodes.Callvirt, getEnumeratorMethod); il.Emit(EmitOpCodes.Stloc, enumerator); var topOfLoop = il.DefineLabel(); var end = il.DefineLabel(); il.MarkLabel(topOfLoop); il.Emit(EmitOpCodes.Ldloc, enumerator); il.Emit(EmitOpCodes.Callvirt, moveNextMethod); il.Emit(EmitOpCodes.Brfalse, end); il.Emit(EmitOpCodes.Ldloc, enumerator); il.Emit(EmitOpCodes.Callvirt, getCurrentMethod); il.Emit(EmitOpCodes.Stloc, item); Statement.Compile(context, il); il.Emit(EmitOpCodes.Br, topOfLoop); il.MarkLabel(end); il.Emit(EmitOpCodes.Nop); }
public abstract void Compile(EmitCompilerContext context, EmitIl il);
public override void Compile(EmitCompilerContext context, EmitIl il) { var local = Variable.GetData(context); il.Emit(EmitOpCodes.Ldloc, local); }