/// <inheritdoc/> public override void EmitEpilogue(ILGenerator il, PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { // If the return type is a delegate, convert it back into its generic representation var definition = workUnit.Definition; var returnType = definition.ReturnType; if (!returnType.IsDelegate()) { return; } // Convert IntPtr to delegate. (null for IntPtr.Zero) var retMarshalLabel = il.DefineLabel(); il.DeclareLocal(typeof(IntPtr)); // loc_0 il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Brtrue_S, retMarshalLabel); // IntPtr.Zero -> return null il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ret); // IntPtr != Zero -> marshal delegate il.MarkLabel(retMarshalLabel); il.Emit(OpCodes.Ldloc_0); var marshalPointerToDel = _marshalPointerToDel.MakeGenericMethod(workUnit.Definition.ReturnType); il.Emit(OpCodes.Call, marshalPointerToDel); }
public PipelineParseResult(string expr, PipelineParseResults pipelineParseResults, PipelineWorkUnit workUnit) { ParseResult = new ParseResult(ParseResultType.Empty, null); PipelineParseResults = pipelineParseResults; WorkUnit = workUnit; Expr = expr; }
/// <inheritdoc /> public sealed override IEnumerable <PipelineWorkUnit <IntrospectiveMethodInfo> > GenerateImplementation ( PipelineWorkUnit <IntrospectiveMethodInfo> workUnit ) { var definition = workUnit.Definition; if (!(definition.GetWrappedMember() is MethodBuilder builder)) { throw new ArgumentNullException(nameof(workUnit), "Could not unwrap introspective method to method builder."); } EmitAdditionalTypes(TargetModule, workUnit); var passthroughMethod = GeneratePassthroughDefinition(workUnit); var il = builder.GetILGenerator(); EmitPrologue(il, workUnit); il.EmitCallDirect(passthroughMethod.GetWrappedMember()); EmitEpilogue(il, workUnit); il.EmitReturn(); // Pass through the method yield return(new PipelineWorkUnit <IntrospectiveMethodInfo>(passthroughMethod, workUnit)); }
/// <inheritdoc/> public override void EmitPrologue(ILGenerator il, PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var definition = workUnit.Definition; var parameterTypes = definition.ParameterTypes; il.EmitLoadArgument(0); for (short i = 1; i <= parameterTypes.Count; ++i) { var paramType = parameterTypes[i - 1]; if (IsSpanType(paramType)) { var pinnedLocal = il.DeclareLocal(paramType.GenericTypeArguments[0].MakeByRefType(), true); var getPinnableReferenceMethod = paramType.GetMethod(nameof(Span <byte> .GetPinnableReference), BindingFlags.Public | BindingFlags.Instance); il.EmitLoadArgumentAddress(i); il.EmitCallDirect(getPinnableReferenceMethod); il.EmitDuplicate(); il.EmitSetLocalVariable(pinnedLocal); il.EmitConvertToNativeInt(); } else { il.EmitLoadArgument(i); } } }
/// <summary> /// Emits any additional types that a work unit requires. By default, this does nothing. /// </summary> /// <param name="module">The module to emit the types in.</param> /// <param name="workUnit">The unit to generate the types from.</param> public virtual void EmitAdditionalTypes ( [NotNull] ModuleBuilder module, [NotNull] PipelineWorkUnit <IntrospectiveMethodInfo> workUnit ) { }
/// <inheritdoc/> public override IntrospectiveMethodInfo GeneratePassthroughDefinition ( PipelineWorkUnit <IntrospectiveMethodInfo> workUnit ) { var definition = workUnit.Definition; var newReturnType = GetParameterPassthroughType(definition.ReturnType); var newParameterTypes = definition.ParameterTypes.Select(GetParameterPassthroughType).ToArray(); var passthroughMethod = TargetType.DefineMethod ( $"{workUnit.GetUniqueBaseMemberName()}_wrapped", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.Standard, newReturnType, newParameterTypes ); passthroughMethod.ApplyCustomAttributesFrom(definition, newReturnType, newParameterTypes); return(new IntrospectiveMethodInfo ( passthroughMethod, newReturnType, newParameterTypes, definition.MetadataType, definition )); }
/// <inheritdoc /> public override void EmitPrologue(ILGenerator il, PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var definition = workUnit.Definition; var locals = new Dictionary <int, LocalBuilder>(); _workUnitLocals.Add(workUnit, locals); // Load the "this" reference il.EmitLoadArgument(0); for (short i = 1; i <= definition.ParameterTypes.Count; ++i) { il.EmitLoadArgument(i); var parameterType = definition.ParameterTypes[i - 1]; if (parameterType != typeof(string)) { continue; } var unmanagedStringType = GetParameterUnmanagedType(definition.ParameterCustomAttributes[i - 1]); il.EmitCallDirect(SelectManagedToUnmanagedTransformationMethod(unmanagedStringType)); if (definition.ParameterHasCustomAttribute <CallerFreeAttribute>(i - 1)) { var parameterLocal = il.DeclareLocal(typeof(IntPtr)); il.EmitSetLocalVariable(parameterLocal); il.EmitLoadLocalVariable(parameterLocal); locals.Add(i - 1, parameterLocal); } } }
/// <inheritdoc /> public override void EmitEpilogue(ILGenerator il, PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { ConstructorInfo ctor = workUnit.Definition.ReturnType.GetConstructor(new[] { typeof(void *), typeof(int) }); il.Emit(OpCodes.Ldc_I4, GetNativeCollectionLengthMetadata(workUnit.Definition).Length); il.Emit(OpCodes.Newobj, ctor); }
public PipelineParseResult(string expr, PipelineParseResults pipelineParseResults, PipelineWorkUnit workUnit, ParseResult parseResult) { ParseResult = parseResult; PipelineParseResults = pipelineParseResults; WorkUnit = workUnit; Expr = expr; }
/// <inheritdoc/> public override void EmitPrologue(ILGenerator il, PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var definition = workUnit.Definition; // Load the "this" reference il.EmitLoadArgument(0); for (short i = 1; i <= definition.ParameterTypes.Count; ++i) { il.EmitLoadArgument(i); var parameterType = definition.ParameterTypes[i - 1]; if (!parameterType.IsGenericDelegate()) { continue; } // Convert the input generic delegate to an explicit delegate var explicitDelegateType = GetCreatedExplicitDelegateType(parameterType); if (explicitDelegateType is null) { throw new InvalidOperationException("No delegate type has been created for the given type."); } var explicitDelegateConstructor = explicitDelegateType.GetConstructors().First(); var invokeMethod = parameterType.GetMethod("Invoke"); il.EmitLoadFunctionPointer(invokeMethod); il.EmitNewObject(explicitDelegateConstructor); } }
/// <inheritdoc/> public override void EmitEpilogue(ILGenerator il, PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { // If the return type is a delegate, convert it back into its generic representation var definition = workUnit.Definition; var returnType = definition.ReturnType; if (!returnType.IsGenericDelegate()) { return; } // Convert the output explicit delegate to a generic delegate var explicitDelegateType = GetCreatedExplicitDelegateType(returnType); if (explicitDelegateType is null) { throw new InvalidOperationException("No delegate type has been created for the given type."); } var genericDelegateConstructor = returnType.GetConstructors().First(); var invokeMethod = explicitDelegateType.GetMethod("Invoke"); il.EmitLoadFunctionPointer(invokeMethod); il.EmitNewObject(genericDelegateConstructor); }
/// <inheritdoc /> public override IntrospectiveMethodInfo GeneratePassthroughDefinition(PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var definition = workUnit.Definition; var newParameterTypes = definition.ParameterTypes.Select(t => t.IsNonRefNullable() ? typeof(IntPtr) : t).ToArray(); var newReturnType = definition.ReturnType.IsNonRefNullable() ? typeof(IntPtr) : definition.ReturnType; var passthroughMethod = TargetType.DefineMethod ( $"{workUnit.GetUniqueBaseMemberName()}_wrapped", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.HideBySig, newReturnType, newParameterTypes ); // Copy over all the attributes, except MarshalAsAttributes to IntPtr parameters passthroughMethod.ApplyCustomAttributesFrom ( definition, newReturnType, newParameterTypes ); return(new IntrospectiveMethodInfo(passthroughMethod, newReturnType, newParameterTypes, definition)); }
/// <inheritdoc /> public override void EmitPrologue(ILGenerator il, PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var throwMethod = typeof(NativeLibraryBase).GetMethod("ThrowIfDisposed", NonPublic | Instance); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, throwMethod); // Emit the parameters as usual base.EmitPrologue(il, workUnit); }
/// <inheritdoc /> public virtual void EmitPrologue(ILGenerator il, PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { // Load the "this" reference il.EmitLoadArgument(0); for (short i = 1; i <= workUnit.Definition.ParameterTypes.Count; ++i) { il.EmitLoadArgument(i); } }
/// <inheritdoc /> public override void EmitEpilogue(ILGenerator il, PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var returnType = workUnit.Definition.ReturnType; if (IsSpanType(returnType)) { il.EmitConstantInt(GetNativeCollectionLengthMetadata(workUnit.Definition).Length); il.EmitNewObject(returnType.GetConstructor(new[] { typeof(void *), typeof(int) })); } }
/// <inheritdoc /> public override void EmitEpilogue(ILGenerator il, PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var definition = workUnit.Definition; var locals = _workUnitLocals[workUnit]; if (locals.Any()) { // We have cleanup to do (freeing unmanaged string memory) foreach (var localCombo in locals) { var parameterIndex = localCombo.Key; var local = localCombo.Value; var unmanagedStringType = GetParameterUnmanagedType(definition.ParameterCustomAttributes[parameterIndex]); il.EmitLoadLocalVariable(local); il.EmitCallDirect(SelectUnmanagedFreeMethod(unmanagedStringType)); } _workUnitLocals.Remove(workUnit); } if (definition.ReturnType != typeof(string)) { return; } var unmanagedReturnStringType = GetParameterUnmanagedType(definition.ReturnParameterCustomAttributes); if (definition.ReturnParameterHasCustomAttribute <CallerFreeAttribute>()) { var ptrLocal = il.DeclareLocal(typeof(IntPtr)); var returnLocal = il.DeclareLocal(typeof(string)); // Store the pointer returned from native code il.EmitSetLocalVariable(ptrLocal); // Marshal the string from the pointer, and store it il.EmitLoadLocalVariable(ptrLocal); il.EmitCallDirect(SelectUnmanagedToManagedTransformationMethod(unmanagedReturnStringType)); il.EmitSetLocalVariable(returnLocal); // Free the pointer il.EmitLoadLocalVariable(ptrLocal); il.EmitCallDirect(SelectUnmanagedFreeMethod(unmanagedReturnStringType)); // Load the string il.EmitLoadLocalVariable(returnLocal); } else { il.EmitCallDirect(SelectUnmanagedToManagedTransformationMethod(unmanagedReturnStringType)); } }
/// <inheritdoc /> public override void EmitEpilogue(ILGenerator il, PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var definition = workUnit.Definition; if (definition.ReturnType != typeof(bool)) { return; } var unmanagedType = GetParameterUnmanagedType(definition.ReturnParameterCustomAttributes); EmitUnmanagedIntegerToBooleanConversion(il, unmanagedType); }
public virtual IntrospectiveMethodInfo GeneratePassthroughDefinition([NotNull] PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var definition = workUnit.Definition; var passthroughMethod = TargetType.DefineMethod ( $"{workUnit.GetUniqueBaseMemberName()}_wrapper", Private | Virtual | HideBySig, CallingConventions.Standard, definition.ReturnType, definition.ParameterTypes.ToArray() ); passthroughMethod.ApplyCustomAttributesFrom(workUnit.Definition); return(new IntrospectiveMethodInfo(passthroughMethod, definition.ReturnType, definition.ParameterTypes, definition)); }
private TypeBuilder GenerateDelegateType ( [NotNull] PipelineWorkUnit <IntrospectiveMethodInfo> workUnit ) { var definition = workUnit.Definition; // Declare a delegate type var delegateBuilder = TargetModule.DefineDelegate ( $"{workUnit.GetUniqueBaseMemberName()}_delegate", definition, Options.HasFlagFast(SuppressSecurity) ); return(delegateBuilder); }
/// <inheritdoc/> public override void EmitPrologue(ILGenerator il, PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var definition = workUnit.Definition; il.EmitLoadArgument(0); for (short i = 1; i <= definition.ParameterTypes.Count; ++i) { var parameterType = definition.ParameterTypes[i - 1]; if (!parameterType.IsDelegate()) { il.EmitLoadArgument(i); continue; } var lifetime = GetParameterDelegateLifetime(definition.ParameterCustomAttributes[i - 1]); if (lifetime == DelegateLifetime.Persistent) { // Keep delegate alive. // Load this il.EmitLoadArgument(0); il.EmitLoadArgument(i); il.Emit(OpCodes.Call, _allocMethod); } // Convert delegate to IntPtr. (IntPtr.Zero for null) var marshalToPtrLabel = il.DefineLabel(); var endLabel = il.DefineLabel(); il.EmitLoadArgument(i); il.Emit(OpCodes.Brtrue_S, marshalToPtrLabel); // Delegate is null -> load IntPtr.Zero and branch to end... il.Emit(OpCodes.Ldsfld, _intPtrZero); il.Emit(OpCodes.Br_S, endLabel); // Delegate is non null -> call Marshal.GetFunctionPointerForDelegate and load it's resulting IntPtr... il.MarkLabel(marshalToPtrLabel); il.EmitLoadArgument(i); il.Emit(OpCodes.Call, _marshalDelToPointer); il.MarkLabel(endLabel); } }
/// <inheritdoc/> public override void EmitAdditionalTypes ( ModuleBuilder module, PipelineWorkUnit <IntrospectiveMethodInfo> workUnit ) { var definition = workUnit.Definition; foreach (var parameterType in definition.ParameterTypes.Concat(new[] { definition.ReturnType })) { if (!parameterType.IsGenericDelegate()) { continue; } EmitExplicitDelegateDefinition(module, parameterType); } }
/// <inheritdoc /> public override void EmitPrologue(ILGenerator il, PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var definition = workUnit.Definition; // Load the "this" reference il.EmitLoadArgument(0); for (short i = 1; i <= definition.ParameterTypes.Count; ++i) { il.EmitLoadArgument(i); var parameterType = definition.ParameterTypes[i - 1]; if (parameterType != typeof(bool)) { continue; } // Convert the input boolean to an unmanaged integer var unmanagedType = GetParameterUnmanagedType(definition.ParameterCustomAttributes[i - 1]); EmitBooleanToUnmanagedIntegerConversion(il, unmanagedType); } }
/// <inheritdoc /> public override IntrospectiveMethodInfo GeneratePassthroughDefinition(PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { if (!workUnit.Definition.ReturnType.GenericTypeArguments[0].IsValueType) { // Span<byte> is used because unbound generics are not allowed inside a nameof, and it still results as just 'Span' throw new NotSupportedException($"Method is not a {nameof(ValueType)} and cannot be marshaled as a {nameof(Span<byte>)}. Marshalling {nameof(Span<byte>)}" + $"requires the marshaled type T in {nameof(Span<byte>)}<T> to be a {nameof(ValueType)}"); } var definition = workUnit.Definition; Type newReturnType = definition.ReturnType.GenericTypeArguments[0].MakePointerType(); /* TODO? Add marshaling for Span<> params */ Type[] parametersTypes = definition.ParameterTypes.ToArray(); MethodBuilder passthroughMethod = TargetType.DefineMethod ( $"{workUnit.GetUniqueBaseMemberName()}_wrapped", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.Standard, newReturnType, parametersTypes ); passthroughMethod.ApplyCustomAttributesFrom(definition, newReturnType, parametersTypes); return(new IntrospectiveMethodInfo ( passthroughMethod, newReturnType, parametersTypes, definition.MetadataType, definition )); }
/// <inheritdoc /> public override IEnumerable <PipelineWorkUnit <IntrospectiveMethodInfo> > GenerateImplementation(PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var definition = workUnit.Definition; var backingFieldType = typeof(IntPtr); var backingField = Options.HasFlagFast(UseLazyBinding) ? TargetType.DefineField ( $"{workUnit.GetUniqueBaseMemberName()}_ptr_lazy", typeof(Lazy <>).MakeGenericType(backingFieldType), FieldAttributes.Private | FieldAttributes.InitOnly ) : TargetType.DefineField ( $"{workUnit.GetUniqueBaseMemberName()}_ptr", backingFieldType, FieldAttributes.Private | FieldAttributes.InitOnly ); AugmentHostingTypeConstructorWithNativeInitialization(workUnit.SymbolName, backingFieldType, backingField); GenerateNativeInvokerBody(definition, definition.GetNativeCallingConvention(), backingField); yield break; }
/// <inheritdoc /> public override IntrospectiveMethodInfo GeneratePassthroughDefinition(PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var returnType = workUnit.Definition.ReturnType; Type newReturnType; var definition = workUnit.Definition; if (IsSpanType(returnType)) { var genericType = returnType.GenericTypeArguments[0]; if (!genericType.IsUnmanaged()) { throw new NotSupportedException($"Method return type must be blittable."); } newReturnType = genericType.MakePointerType(); } else { newReturnType = returnType; } var parametersTypes = definition.ParameterTypes.ToArray(); for (int i = 0; i < parametersTypes.Length; ++i) { var paramType = parametersTypes[i]; if (IsSpanType(paramType)) { var genericParam = paramType.GenericTypeArguments[0]; if (genericParam.IsGenericType) { throw new NotSupportedException("Generic type found as Span generic argument"); } if (!genericParam.IsUnmanaged()) { throw new NotSupportedException("Reference or value type containing references found in Span<T> or ReadOnlySpan<T> generic parameter."); } parametersTypes[i] = genericParam.MakePointerType(); // genercParam.MakePointerType(); } } MethodBuilder passthroughMethod = TargetType.DefineMethod ( $"{workUnit.GetUniqueBaseMemberName()}_wrapped", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.Standard, newReturnType, parametersTypes ); passthroughMethod.ApplyCustomAttributesFrom(definition, newReturnType, parametersTypes); return(new IntrospectiveMethodInfo ( passthroughMethod, newReturnType, parametersTypes, definition.MetadataType, definition )); }
/// <inheritdoc /> public override void EmitPrologue(ILGenerator il, PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var definition = workUnit.Definition; var locals = new Dictionary <int, LocalBuilder>(); _workUnitLocals.Add(workUnit, locals); // Load the "this" reference il.EmitLoadArgument(0); for (short i = 1; i <= definition.ParameterTypes.Count; ++i) { var parameterType = definition.ParameterTypes[i - 1]; if (!parameterType.IsNonRefNullable()) { il.EmitLoadArgument(i); continue; } var nullableType = parameterType.GetGenericArguments().First(); var hasValueMethod = GetHasValueMethod(nullableType); var getValueMethod = GetGetValueMethod(nullableType); var hasValueLabel = il.DefineLabel(); var branchEnd = il.DefineLabel(); var ptrLocal = il.DeclareLocal(typeof(IntPtr)); il.EmitLoadArgumentAddress(i); il.EmitCallDirect(hasValueMethod); il.EmitBranchTrue(hasValueLabel); // false case - no value, pass null { il.EmitLoadStaticField(_nullPtrField); il.EmitBranch(branchEnd); } // true case - marshal the structure to a pointer, pass it il.MarkLabel(hasValueLabel); { il.EmitSizeOf(nullableType); il.EmitCallDirect(_allocHGlobalMethod); il.EmitSetLocalVariable(ptrLocal); il.EmitLoadArgumentAddress(i); il.EmitCallDirect(getValueMethod); il.EmitBox(nullableType); il.EmitLoadLocalVariable(ptrLocal); il.EmitConstantInt(0); il.EmitCallDirect(_structureToPtrMethod); il.EmitLoadLocalVariable(ptrLocal); } il.MarkLabel(branchEnd); if (definition.ParameterHasCustomAttribute <CallerFreeAttribute>(i - 1)) { il.EmitSetLocalVariable(ptrLocal); il.EmitLoadLocalVariable(ptrLocal); locals.Add(i - 1, ptrLocal); } } }
/// <inheritdoc /> public override void EmitEpilogue(ILGenerator il, PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var definition = workUnit.Definition; var locals = _workUnitLocals[workUnit]; if (locals.Any()) { // We have cleanup to do (freeing unmanaged structure memory) foreach (var localCombo in locals) { var local = localCombo.Value; var hasPointerLabel = il.DefineLabel(); var branchEnd = il.DefineLabel(); // Check if we have a pointer to clean up il.EmitLoadLocalVariable(local); il.EmitLoadStaticField(_nullPtrField); il.EmitCallDirect(_ptrInequalityOperator); il.EmitBranchTrue(hasPointerLabel); // false case, null pointer { il.EmitBranch(branchEnd); } // true case, has pointer il.MarkLabel(hasPointerLabel); { il.EmitLoadLocalVariable(local); il.EmitCallDirect(_freeHGlobalMethod); } il.MarkLabel(branchEnd); } _workUnitLocals.Remove(workUnit); } if (!definition.ReturnType.IsNonRefNullable()) { return; } var nullableType = definition.ReturnType.GetGenericArguments().First(); var ptrToStructureMethod = _ptrToStructureMethodBase.MakeGenericMethod(nullableType); var returnIsNotNullLabel = il.DefineLabel(); var returnBranchEndLabel = il.DefineLabel(); var closedNullableType = typeof(Nullable <>).MakeGenericType(nullableType); var returnLocal = il.DeclareLocal(closedNullableType); var ptrLocal = il.DeclareLocal(typeof(IntPtr)); // Store the pointer returned from native code il.EmitSetLocalVariable(ptrLocal); // Check if we have a valid value il.EmitLoadLocalVariable(ptrLocal); il.EmitLoadStaticField(_nullPtrField); il.EmitCallDirect(_ptrInequalityOperator); il.EmitBranchTrue(returnIsNotNullLabel); // false case, return null { il.EmitLoadLocalVariableAddress(returnLocal); il.EmitInitObject(closedNullableType); il.EmitLoadLocalVariable(returnLocal); il.EmitBranch(returnBranchEndLabel); } // true case, return marshalled structure il.MarkLabel(returnIsNotNullLabel); { // Marshal the structure from the pointer il.EmitLoadLocalVariable(ptrLocal); il.EmitCallDirect(ptrToStructureMethod); if (definition.ReturnParameterHasCustomAttribute <CallerFreeAttribute>()) { var marshalledReturnLocal = il.DeclareLocal(nullableType); // And store it il.EmitSetLocalVariable(marshalledReturnLocal); // Free the pointer il.EmitLoadLocalVariable(ptrLocal); il.EmitCallDirect(_freeHGlobalMethod); // Load the structure il.EmitLoadLocalVariable(marshalledReturnLocal); } il.EmitNewObject(GetNullableConstructor(nullableType)); } il.MarkLabel(returnBranchEndLabel); }
/// <inheritdoc /> public override IEnumerable <PipelineWorkUnit <IntrospectiveMethodInfo> > GenerateImplementation(PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var permutations = new List <IntrospectiveMethodInfo>(); var definition = workUnit.Definition; // Generate permutation definitions var parameterPermutations = _permutationGenerator.Generate(definition); for (int i = 0; i < parameterPermutations.Count; ++i) { var permutation = parameterPermutations[i]; var method = TargetType.DefineMethod ( $"{workUnit.GetUniqueBaseMemberName()}_permutation_{i}", Public | Final | Virtual | HideBySig | NewSlot, CallingConventions.Standard, definition.ReturnType, permutation.ToArray() ); var methodInfo = new IntrospectiveMethodInfo(method, definition.ReturnType, permutation, definition); permutations.Add(methodInfo); } GenerateTopLevelMethodImplementation(definition, permutations); // Pass the permutations on for further processing foreach (var permutation in permutations) { yield return(new PipelineWorkUnit <IntrospectiveMethodInfo>(permutation, workUnit)); } }
/// <inheritdoc /> public override IEnumerable <PipelineWorkUnit <IntrospectiveMethodInfo> > GenerateImplementation(PipelineWorkUnit <IntrospectiveMethodInfo> workUnit) { var definition = workUnit.Definition; var delegateBuilder = GenerateDelegateType(workUnit); // Create a delegate field var backingFieldType = delegateBuilder.CreateTypeInfo(); var backingField = Options.HasFlagFast(UseLazyBinding) ? TargetType.DefineField ( $"{workUnit.GetUniqueBaseMemberName()}_delegate_lazy", typeof(Lazy <>).MakeGenericType(backingFieldType), FieldAttributes.Private | FieldAttributes.InitOnly ) : TargetType.DefineField ( $"{workUnit.GetUniqueBaseMemberName()}_delegate", backingFieldType, FieldAttributes.Private | FieldAttributes.InitOnly ); AugmentHostingTypeConstructorWithDelegateInitialization(workUnit.SymbolName, backingFieldType, backingField); GenerateDelegateInvokerBody(definition, backingFieldType, backingField); yield break; }
/// <inheritdoc /> public override IEnumerable <PipelineWorkUnit <IntrospectivePropertyInfo> > GenerateImplementation(PipelineWorkUnit <IntrospectivePropertyInfo> workUnit) { var property = workUnit.Definition; var propertyBuilder = TargetType.DefineProperty ( property.Name, PropertyAttributes.None, CallingConventions.HasThis, property.PropertyType, property.IndexParameterTypes.ToArray() ); // Note, the field is going to have to be a pointer, because it is pointing to global variable var fieldType = Options.HasFlagFast(UseLazyBinding) ? typeof(Lazy <IntPtr>) : typeof(IntPtr); var propertyFieldBuilder = TargetType.DefineField ( $"{workUnit.GetUniqueBaseMemberName()}_backing", fieldType, FieldAttributes.Private ); if (property.CanRead) { GeneratePropertyGetter(property, propertyFieldBuilder, propertyBuilder); } if (property.CanWrite) { GeneratePropertySetter(property, propertyFieldBuilder, propertyBuilder); } AugmentHostingTypeConstructor(workUnit.SymbolName, propertyFieldBuilder); yield break; }