public override void Emit(FleeILGenerator ilg, IServiceProvider services) { var binaryResultType = ImplicitConverter.GetBinaryResultType(MyLeftChild.ResultType, MyRightChild.ResultType); var overloadedOperator = this.GetOverloadedCompareOperator(); if (this.AreBothChildrenOfType(typeof(string))) { // String equality MyLeftChild.Emit(ilg, services); MyRightChild.Emit(ilg, services); EmitStringEquality(ilg, MyOperation, services); } else if ((overloadedOperator != null)) { base.EmitOverloadedOperatorCall(overloadedOperator, ilg, services); } else if ((binaryResultType != null)) { // Emit a compare of numeric operands EmitChildWithConvert(MyLeftChild, binaryResultType, ilg, services); EmitChildWithConvert(MyRightChild, binaryResultType, ilg, services); EmitCompareOperation(ilg, MyOperation); } else if (this.AreBothChildrenOfType(typeof(bool))) { // Boolean equality this.EmitRegular(ilg, services); } else if (this.AreBothChildrenReferenceTypes() == true) { // Reference equality this.EmitRegular(ilg, services); } else if (MyLeftChild.ResultType.IsEnum == true & MyRightChild.ResultType.IsEnum == true) { this.EmitRegular(ilg, services); } else { Debug.Fail("unknown operand types"); } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { base.Emit(ilg, services); MyElement.Emit(ilg, services); if (MyElement.ResultType.IsValueType == true) { EmitValueTypeLoadAddress(ilg, this.ResultType); } }
protected static void EmitLoad(bool value, FleeILGenerator ilg) { if (value == true) { ilg.Emit(OpCodes.Ldc_I4_1); } else { ilg.Emit(OpCodes.Ldc_I4_0); } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { if (object.ReferenceEquals(MyChild.ResultType, typeof(bool))) { this.EmitLogical(ilg, services); } else { MyChild.Emit(ilg, services); ilg.Emit(OpCodes.Not); } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { var resultType = this.ResultType; MyLeftChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyLeftChild.ResultType, resultType, ilg); MyRightChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyRightChild.ResultType, resultType, ilg); ilg.Emit(OpCodes.Xor); }
public static void EmitLoad(Int32 value, FleeILGenerator ilg) { if (value >= -1 & value <= 8) { EmitSuperShort(value, ilg); } else if (value >= sbyte.MinValue & value <= sbyte.MaxValue) { ilg.Emit(OpCodes.Ldc_I4_S, Convert.ToSByte(value)); } else { ilg.Emit(OpCodes.Ldc_I4, value); } }
protected static void EmitLoad(Int64 value, FleeILGenerator ilg) { if (value >= Int32.MinValue & value <= Int32.MaxValue) { EmitLoad((int)value, ilg); ilg.Emit(OpCodes.Conv_I8); } else if (value >= 0 & value <= UInt32.MaxValue) { EmitLoad((int)value, ilg); ilg.Emit(OpCodes.Conv_U8); } else { ilg.Emit(OpCodes.Ldc_I8, value); } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { MyChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyChild.ResultType, MyResultType, ilg); var options = (ExpressionOptions)services.GetService(typeof(ExpressionOptions)); if (options.IsGeneric == false) { ImplicitConverter.EmitImplicitConvert(MyResultType, typeof(object), ilg); } ilg.Emit(OpCodes.Ret); }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { Type resultType = this.ResultType; MyChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyChild.ResultType, resultType, ilg); MethodInfo mi = Utility.GetSimpleOverloadedOperator("UnaryNegation", resultType, resultType); if (mi == null) { ilg.Emit(OpCodes.Neg); } else { ilg.Emit(OpCodes.Call, mi); } }
public override void Emit(FleeILGenerator ilg, System.IServiceProvider services) { int index = ilg.GetTempLocalIndex(typeof(DateTime)); Utility.EmitLoadLocalAddress(ilg, index); LiteralElement.EmitLoad(MyValue.Ticks, ilg); ConstructorInfo ci = typeof(DateTime).GetConstructor(new Type[] { typeof(long) }); ilg.Emit(OpCodes.Call, ci); Utility.EmitLoadLocal(ilg, index); }
private static void EmitBitwiseOperation(FleeILGenerator ilg, AndOrOperation op) { switch (op) { case AndOrOperation.And: ilg.Emit(OpCodes.And); break; case AndOrOperation.Or: ilg.Emit(OpCodes.Or); break; default: Debug.Fail("Unknown op type"); break; } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { Type resultType = this.ResultType; if (object.ReferenceEquals(resultType, typeof(bool))) { this.DoEmitLogical(ilg, services); } else { MyLeftChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyLeftChild.ResultType, resultType, ilg); MyRightChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyRightChild.ResultType, resultType, ilg); EmitBitwiseOperation(ilg, MyOperation); } }
private void EmitConditional(FleeILGenerator ilg, IServiceProvider services, BranchManager bm) { var falseLabel = bm.FindLabel("falseLabel"); var endLabel = bm.FindLabel("endLabel"); // Emit the condition MyCondition.Emit(ilg, services); // On false go to the false operand if (ilg.IsTemp == true) { bm.AddBranch(ilg, falseLabel); ilg.Emit(OpCodes.Brfalse_S, falseLabel); } else if (bm.IsLongBranch(ilg, falseLabel) == false) { ilg.Emit(OpCodes.Brfalse_S, falseLabel); } else { ilg.Emit(OpCodes.Brfalse, falseLabel); } // Emit the true operand MyWhenTrue.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyWhenTrue.ResultType, MyResultType, ilg); // Jump to end if (ilg.IsTemp == true) { bm.AddBranch(ilg, endLabel); ilg.Emit(OpCodes.Br_S, endLabel); } else if (bm.IsLongBranch(ilg, endLabel) == false) { ilg.Emit(OpCodes.Br_S, endLabel); } else { ilg.Emit(OpCodes.Br, endLabel); } bm.MarkLabel(ilg, falseLabel); ilg.MarkLabel(falseLabel); // Emit the false operand MyWhenFalse.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyWhenFalse.ResultType, MyResultType, ilg); // Fall through to end bm.MarkLabel(ilg, endLabel); ilg.MarkLabel(endLabel); }
private static void EmitSuperShort(Int32 value, FleeILGenerator ilg) { OpCode ldcOpcode = default(OpCode); switch (value) { case 0: ldcOpcode = OpCodes.Ldc_I4_0; break; case 1: ldcOpcode = OpCodes.Ldc_I4_1; break; case 2: ldcOpcode = OpCodes.Ldc_I4_2; break; case 3: ldcOpcode = OpCodes.Ldc_I4_3; break; case 4: ldcOpcode = OpCodes.Ldc_I4_4; break; case 5: ldcOpcode = OpCodes.Ldc_I4_5; break; case 6: ldcOpcode = OpCodes.Ldc_I4_6; break; case 7: ldcOpcode = OpCodes.Ldc_I4_7; break; case 8: ldcOpcode = OpCodes.Ldc_I4_8; break; case -1: ldcOpcode = OpCodes.Ldc_I4_M1; break; default: Debug.Assert(false, "value out of range"); break; } ilg.Emit(ldcOpcode); }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { int index = ilg.GetTempLocalIndex(typeof(decimal)); Utility.EmitLoadLocalAddress(ilg, index); int[] bits = decimal.GetBits(MyValue); EmitLoad(bits[0], ilg); EmitLoad(bits[1], ilg); EmitLoad(bits[2], ilg); int flags = bits[3]; EmitLoad((flags >> 31) == -1, ilg); EmitLoad(flags >> 16, ilg); ilg.Emit(OpCodes.Call, OurConstructorInfo); Utility.EmitLoadLocal(ilg, index); }
public static void EmitStoreLocal(FleeILGenerator ilg, int index) { if (index >= 0 & index <= 3) { switch (index) { case 0: ilg.Emit(OpCodes.Stloc_0); break; case 1: ilg.Emit(OpCodes.Stloc_1); break; case 2: ilg.Emit(OpCodes.Stloc_2); break; case 3: ilg.Emit(OpCodes.Stloc_3); break; } } else { Debug.Assert(index < 256, "local index too large"); ilg.Emit(OpCodes.Stloc_S, Convert.ToByte(index)); } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { var bm = new BranchManager(); bm.GetLabel("falseLabel", ilg); bm.GetLabel("endLabel", ilg); if (ilg.IsTemp == true) { // If this is a fake emit, then do a fake emit and return this.EmitConditional(ilg, services, bm); return; } var ilgTemp = this.CreateTempFleeILGenerator(ilg); Utility.SyncFleeILGeneratorLabels(ilg, ilgTemp); // Emit fake conditional to get branch target positions this.EmitConditional(ilgTemp, services, bm); bm.ComputeBranches(); // Emit real conditional now that we have the branch target locations this.EmitConditional(ilg, services, bm); }
protected static void EmitValueTypeLoadAddress(FleeILGenerator ilg, Type targetType) { int index = ilg.GetTempLocalIndex(targetType); Utility.EmitStoreLocal(ilg, index); ilg.Emit(OpCodes.Ldloca_S, Convert.ToByte(index)); }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { MyTail.Emit(ilg, services); }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { if ((MyPrevious != null)) { MyPrevious.Emit(ilg, services); } }
protected void EmitLoadOwner(FleeILGenerator ilg) { ilg.Emit(OpCodes.Ldarg_0); Type ownerType = MyOptions.OwnerType; if (ownerType.IsValueType == false) { return; } ilg.Emit(OpCodes.Unbox, ownerType); ilg.Emit(OpCodes.Ldobj, ownerType); // Emit usual stuff for value types but use the owner type as the target if (this.RequiresAddress == true) { EmitValueTypeLoadAddress(ilg, ownerType); } }
private static void EmitBranchToTrueTerminal(FleeILGenerator ilg, Label trueTerminal, BranchManager bm) { if (ilg.IsTemp == true) { bm.AddBranch(ilg, trueTerminal); ilg.Emit(OpCodes.Brtrue_S, trueTerminal); } else if (bm.IsLongBranch(ilg, trueTerminal) == false) { ilg.Emit(OpCodes.Brtrue_S, trueTerminal); } else { ilg.Emit(OpCodes.Brtrue, trueTerminal); } }
protected static void EmitLoadVariables(FleeILGenerator ilg) { ilg.Emit(OpCodes.Ldarg_2); }
private void EmitCollectionIn(FleeILGenerator ilg, IServiceProvider services) { // Get the contains method var mi = this.GetCollectionContainsMethod(); var p1 = mi.GetParameters()[0]; // Load the collection MyTargetCollectionElement.Emit(ilg, services); // Load the argument MyOperand.Emit(ilg, services); // Do an implicit convert if necessary ImplicitConverter.EmitImplicitConvert(MyOperand.ResultType, p1.ParameterType, ilg); // Call the contains method ilg.Emit(OpCodes.Callvirt, mi); }
private void EmitListIn(FleeILGenerator ilg, IServiceProvider services, BranchManager bm) { var ce = new CompareElement(); var endLabel = bm.FindLabel("endLabel"); var trueTerminal = bm.FindLabel("trueTerminal"); // Cache the operand since we will be comparing against it a lot var lb = ilg.DeclareLocal(MyOperand.ResultType); int targetIndex = lb.LocalIndex; MyOperand.Emit(ilg, services); Utility.EmitStoreLocal(ilg, targetIndex); // Wrap our operand in a local shim var targetShim = new LocalBasedElement(MyOperand, targetIndex); // Emit the compares foreach (var argumentElement in MyArguments) { ce.Initialize(targetShim, argumentElement, LogicalCompareOperation.Equal); ce.Emit(ilg, services); EmitBranchToTrueTerminal(ilg, trueTerminal, bm); } ilg.Emit(OpCodes.Ldc_I4_0); ilg.Emit(OpCodes.Br_S, endLabel); bm.MarkLabel(ilg, trueTerminal); ilg.MarkLabel(trueTerminal); ilg.Emit(OpCodes.Ldc_I4_1); bm.MarkLabel(ilg, endLabel); ilg.MarkLabel(endLabel); }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { if ((MyTargetCollectionType != null)) { this.EmitCollectionIn(ilg, services); } else { var bm = new BranchManager(); bm.GetLabel("endLabel", ilg); bm.GetLabel("trueTerminal", ilg); // Do a fake emit to get branch positions var ilgTemp = this.CreateTempFleeILGenerator(ilg); Utility.SyncFleeILGeneratorLabels(ilg, ilgTemp); this.EmitListIn(ilgTemp, services, bm); bm.ComputeBranches(); // Do the real emit this.EmitListIn(ilg, services, bm); } }
public static void EmitArrayStore(FleeILGenerator ilg, Type elementType) { TypeCode tc = Type.GetTypeCode(elementType); switch (tc) { case TypeCode.Byte: case TypeCode.SByte: case TypeCode.Boolean: ilg.Emit(OpCodes.Stelem_I1); break; case TypeCode.Int16: case TypeCode.UInt16: ilg.Emit(OpCodes.Stelem_I2); break; case TypeCode.Int32: case TypeCode.UInt32: ilg.Emit(OpCodes.Stelem_I4); break; case TypeCode.Int64: case TypeCode.UInt64: ilg.Emit(OpCodes.Stelem_I8); break; case TypeCode.Single: ilg.Emit(OpCodes.Stelem_R4); break; case TypeCode.Double: ilg.Emit(OpCodes.Stelem_R8); break; case TypeCode.Object: case TypeCode.String: ilg.Emit(OpCodes.Stelem_Ref); break; default: // Must be a non-primitive value type ilg.Emit(OpCodes.Stelem, elementType); break; } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { ilg.Emit(OpCodes.Ldc_R8, MyValue); }
public static void SyncFleeILGeneratorLabels(FleeILGenerator source, FleeILGenerator target) { while (source.LabelCount != target.LabelCount) { target.DefineLabel(); } }
public static void EmitLoadLocalAddress(FleeILGenerator ilg, int index) { Debug.Assert(index >= 0, "Invalid index"); if (index <= byte.MaxValue) { ilg.Emit(OpCodes.Ldloca_S, Convert.ToByte(index)); } else { ilg.Emit(OpCodes.Ldloca, index); } }