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) { Initializer?.Compile(context, il); var start = il.DefineLabel(); var end = il.DefineLabel(); il.MarkLabel(start); if (Predicate != null) { Predicate.Compile(context, il); } else { il.Emit(EmitOpCodes.Ldc_I4_1); } il.Emit(EmitOpCodes.Brfalse, end); Body.Compile(context, il); Incrementor?.Compile(context, il); il.Emit(EmitOpCodes.Br, start); il.MarkLabel(end); }
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 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); }