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) { foreach (var variable in Variables) { var local = il.DeclareLocal(variable.Type); variable.SetData(context, local); } }
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 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) { switch (Operator) { case EmitUnaryOperator.BooleanNot: Operand.Compile(context, il); il.Emit(EmitOpCodes.Ldc_I4_0); il.Emit(EmitOpCodes.Ceq); break; case EmitUnaryOperator.BitwiseNot: Operand.Compile(context, il); il.Emit(EmitOpCodes.Not); break; case EmitUnaryOperator.Minus: Operand.Compile(context, il); il.Emit(EmitOpCodes.Neg); break; case EmitUnaryOperator.Plus: Operand.Compile(context, il); break; case EmitUnaryOperator.PostfixDecrement: { Operand.Compile(context, il); var local = il.DeclareLocal(Operand.GetExpressionType()); il.Emit(EmitOpCodes.Stloc, local); ((IEmitReferenceExpression)Operand).CompileAssignment(context, il, () => { il.Emit(EmitOpCodes.Ldloc, local); il.Emit(EmitOpCodes.Ldc_I4_1); il.Emit(EmitOpCodes.Sub); }); il.Emit(EmitOpCodes.Pop); il.Emit(EmitOpCodes.Ldloc, local); break; } case EmitUnaryOperator.PostfixIncrement: { Operand.Compile(context, il); var local = il.DeclareLocal(Operand.GetExpressionType()); il.Emit(EmitOpCodes.Stloc, local); ((IEmitReferenceExpression)Operand).CompileAssignment(context, il, () => { il.Emit(EmitOpCodes.Ldloc, local); il.Emit(EmitOpCodes.Ldc_I4_1); il.Emit(EmitOpCodes.Add); }); il.Emit(EmitOpCodes.Pop); il.Emit(EmitOpCodes.Ldloc, local); break; } case EmitUnaryOperator.PrefixDecrement: { Operand.Compile(context, il); il.Emit(EmitOpCodes.Ldc_I4_1); il.Emit(EmitOpCodes.Sub); var local = il.DeclareLocal(Operand.GetExpressionType()); il.Emit(EmitOpCodes.Stloc, local); ((IEmitReferenceExpression)Operand).CompileAssignment(context, il, () => { il.Emit(EmitOpCodes.Ldloc, local); }); break; } case EmitUnaryOperator.PrefixIncrement: { Operand.Compile(context, il); il.Emit(EmitOpCodes.Ldc_I4_1); il.Emit(EmitOpCodes.Add); var local = il.DeclareLocal(Operand.GetExpressionType()); il.Emit(EmitOpCodes.Stloc, local); ((IEmitReferenceExpression)Operand).CompileAssignment(context, il, () => { il.Emit(EmitOpCodes.Ldloc, local); }); break; } } }