private void EmitListIn(FleeILGenerator ilg, IServiceProvider services) { CompareElement ce = new CompareElement(); Label endLabel = ilg.DefineLabel(); Label trueTerminal = ilg.DefineLabel(); // Cache the operand since we will be comparing against it a lot LocalBuilder lb = ilg.DeclareLocal(MyOperand.ResultType); int targetIndex = lb.LocalIndex; MyOperand.Emit(ilg, services); Utility.EmitStoreLocal(ilg, targetIndex); // Wrap our operand in a local shim LocalBasedElement targetShim = new LocalBasedElement(MyOperand, targetIndex); // Emit the compares foreach (ExpressionElement argumentElement in MyArguments) { ce.Initialize(targetShim, argumentElement, LogicalCompareOperation.Equal); ce.Emit(ilg, services); EmitBranchToTrueTerminal(ilg, trueTerminal); } ilg.Emit(OpCodes.Ldc_I4_0); ilg.Emit(OpCodes.Br_S, endLabel); ilg.MarkLabel(trueTerminal); ilg.Emit(OpCodes.Ldc_I4_1); ilg.MarkLabel(endLabel); }
/// <summary> /// Emit elements into an array /// </summary> /// <param name="elements"></param> /// <param name="arrayElementType"></param> /// <param name="ilg"></param> /// <param name="services"></param> private static void EmitElementArrayLoad(ExpressionElement[] elements, Type arrayElementType, FleeILGenerator ilg, IServiceProvider services) { // Load the array length LiteralElement.EmitLoad(elements.Length, ilg); // Create the array ilg.Emit(OpCodes.Newarr, arrayElementType); // Store the new array in a unique local and remember the index LocalBuilder local = ilg.DeclareLocal(arrayElementType.MakeArrayType()); int arrayLocalIndex = local.LocalIndex; Utility.EmitStoreLocal(ilg, arrayLocalIndex); for (int i = 0; i <= elements.Length - 1; i++) { // Load the array Utility.EmitLoadLocal(ilg, arrayLocalIndex); // Load the index LiteralElement.EmitLoad(i, ilg); // Emit the element (with any required conversions) ExpressionElement element = elements[i]; element.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(element.ResultType, arrayElementType, ilg); // Store it into the array Utility.EmitArrayStore(ilg, arrayElementType); } // Load the array Utility.EmitLoadLocal(ilg, arrayLocalIndex); }
private void EmitCustomInMethod(FleeILGenerator ilg, IServiceProvider services) { int arraySize = _myArguments.Count; Type arrayElementType = _myOperand.ResultType; Type arrayType = arrayElementType.MakeArrayType(); // Load the array length LdcI4(ilg, arraySize); // Create the array ilg.Emit(OpCodes.Newarr, arrayElementType); // Store the new array in a unique local and remember the index LocalBuilder local = ilg.DeclareLocal(arrayType); int arrayLocalIndex = local.LocalIndex; Utility.EmitStoreLocal(ilg, arrayLocalIndex); for (int i = 0; i < _myArguments.Count; i++) { ExpressionElement argumentElement = _myArguments[i]; // Load the array Utility.EmitLoadLocal(ilg, arrayLocalIndex); // Load the index LdcI4(ilg, i); EmitChild(argumentElement, arrayElementType, ilg, services); // Store it into the array Utility.EmitArrayStore(ilg, arrayElementType); } EmitChild(_myOperand, arrayElementType, ilg, services); // Load the array Utility.EmitLoadLocal(ilg, arrayLocalIndex); MethodInfo genericMethod = s_InMethodInfo.MakeGenericMethod(arrayElementType); ilg.Emit(OpCodes.Call, genericMethod); }