public void EmitAssemblyEntryPoint (AssemblyDefinition assembly, MethodDefinition entryMethod, MethodSignature signature) { Formatter.WriteRaw("JSIL.SetEntryPoint"); Formatter.LPar(); Formatter.AssemblyReference(assembly); Formatter.Comma(); var context = new TypeReferenceContext(); Formatter.TypeReference(entryMethod.DeclaringType, context); Formatter.Comma(); Formatter.Value(entryMethod.Name); Formatter.Comma(); Formatter.MethodSignature( entryMethod, signature, context ); Formatter.RPar(); Formatter.Semicolon(true); Formatter.NewLine(); }
public void Equals_TwoIdenticalSignatures() { var ms1 = new MethodSignature(typeof(MethodSignature).GetConstructors()[1].GetParameters()); var ms2 = new MethodSignature(typeof(MethodSignature).GetConstructors()[1].GetParameters()); Assert.AreEqual(ms1, ms2); }
public void ctor_LegalParameters_InitializeFieldsWithValues() { var target = new MethodSignature(SOME_TYPE_NAME, SOME_METHOD_NAME); Assert.AreEqual(SOME_TYPE_NAME, target.TypeName); Assert.AreEqual(SOME_METHOD_NAME, target.MethodName); }
private static CCDataEntry LocateCCData(MethodSignature method, IList<CCDataEntry> ccData) { var answer = (from data in ccData where data.Method.Equals(method) select data); return answer.SingleOrDefault(); }
public void Equals_TwoDifferentSignaturesSameLength() { var ms1 = new MethodSignature(typeof(Type[]), typeof(object)); var ms2 = new MethodSignature(typeof(Type), typeof(object)); Assert.AreNotEqual(ms1, ms2); }
public void Equals_DifferentMethod_ReturnFalse() { var otherMethod = new MethodSignature(VALID_TYPE_NAME, VALID_METHOD_NAME+"a"); var target1 = new CombinedDataEntry(_Method, 1, 5); var target2 = new CombinedDataEntry(otherMethod, 1, 5); Assert.IsFalse(target1.Equals(target2)); }
internal Native(IntPtr target, Selector selector, IntPtr imp, MethodSignature sig) { Contract.Requires(selector != null, "selector is null"); Contract.Requires(target == IntPtr.Zero || imp != IntPtr.Zero, "imp is null"); m_target = target; if (m_target != IntPtr.Zero) { if (ms_stackFrames == null) ms_stackFrames = new Dictionary<MethodSignature, StackFrame>(); // note that we have to do this here so each thread gets its own dictionary m_selector = selector; m_imp = imp; m_sig = sig ?? new MethodSignature(target, (IntPtr) selector); if (!ms_stackFrames.TryGetValue(m_sig, out m_stackFrame)) { m_stackFrame = new StackFrame(m_sig); ms_stackFrames.Add(m_sig, m_stackFrame); } Ffi.FillBuffer(m_stackFrame.ArgBuffers[0], target, "@"); Ffi.FillBuffer(m_stackFrame.ArgBuffers[1], m_selector, ":"); } }
internal Managed(MethodInfo info, string encoding) { Contract.Requires(info != null, "info is null"); Contract.Requires(!string.IsNullOrEmpty(encoding), "encoding is null or empty"); m_info = info; m_signature = new MethodSignature(encoding); }
public static bool Remove(string conditionFormat, IList<Type> parameterTypes) { lock (_methods) { var signature = new MethodSignature(conditionFormat, parameterTypes); return _methods.Remove(signature); } }
public void ToString_Works() { var ms1 = new MethodSignature(typeof(Type[]), typeof(object)); Assert.AreEqual("(System.Type[], System.Object)", ms1.ToString()); var ms2 = new MethodSignature(new Type[0]); Assert.AreEqual("()", ms2.ToString()); }
public void Equals_NullObject_ReturnsFalse() { var target = new MethodSignature(SOME_TYPE_NAME, SOME_METHOD_NAME + "a"); var actual = target.Equals(null); Assert.IsFalse(actual); }
public void Equals_TwoDifferentSignatures() { var ms1 = new MethodSignature(typeof(Type[]), typeof(object), typeof(string)); var ms2 = new MethodSignature(typeof(Type[]), typeof(object)); Assert.AreNotEqual(ms1, ms2); Assert.IsFalse(ms1.Equals(null)); }
public void Equals_IdenticalValues_ReturnsTrue() { var target1 = new MethodSignature(SOME_TYPE_NAME, SOME_METHOD_NAME); var target2 = new MethodSignature(SOME_TYPE_NAME, SOME_METHOD_NAME); var actual = target1.Equals(target2); Assert.IsTrue(actual); }
public void Equals_DifferentTypeName_ReturnsFalse() { var target1 = new MethodSignature(SOME_TYPE_NAME, SOME_METHOD_NAME + "a"); var target2 = new MethodSignature(SOME_TYPE_NAME, SOME_METHOD_NAME); var actual = target1.Equals(target2); Assert.IsFalse(actual); }
/// <summary> /// Generates a mock object with an interface defined by an array of method signatures. /// </summary> /// <param name="typeName">Name of the type to ganerate.</param> /// <param name="methodSignatures">Array of method signatures of methods to be implemented.</param> /// <param name="handler">Mocked calls handler.</param> /// <returns>Instance of generated class.</returns> public object Generate( string typeName, MethodSignature[] methodSignatures, IMockedCallHandler handler ) { MockClassBuilder classBuilder = new MockClassBuilder( _moduleBuilder, typeName, typeof ( object ), Type.EmptyTypes ); foreach ( MethodSignature ms in methodSignatures ) { classBuilder.ImplementMockedMethod( ms.MethodName, ms.ReturnType, ms.ParamTypes ); } return compileAndGenerateMock( classBuilder, handler ); }
public static object RunMethod(string conditionFormat, object[] parameters) { lock (_methods) { Type[] parameterTypes = parameters.Select(x => x != null ? x.GetType() : typeof(object)).ToArray(); var signature = new MethodSignature(conditionFormat, parameterTypes); Func<object[], object> method; if (_methods.TryGetValue(signature, out method) == false) { _methods[signature] = method = GenerateMethod(conditionFormat, parameterTypes); } return method(parameters); } }
/// <summary> /// Construct a comparer between NativeFormat metadata methods and native layouts /// </summary> /// <param name="metadataReader">Metadata reader for the method declaring type</param> /// <param name="methodHandle">Handle of method to compare</param> public MethodSignatureComparer( MetadataReader metadataReader, MethodHandle methodHandle) { _metadataReader = metadataReader; _methodHandle = methodHandle; _method = methodHandle.GetMethod(metadataReader); _methodSignature = _method.Signature.GetMethodSignature(_metadataReader); _isGeneric = (_methodSignature.GenericParameterCount != 0); // Precalculate initial method attributes used in signature queries _isStatic = (_method.Flags & MethodAttributes.Static) != 0; }
public void VerifyConstructor() { var header = new SignatureHeader(2); var returnType = 5; var requiredParameterCount = 10; var genericParameterCount = 3; var parameterTypes = ImmutableArray.Create(2, 4, 6, 8); var methodSignature = new MethodSignature<int>(header, returnType, requiredParameterCount, genericParameterCount, parameterTypes); // Verify each field was correctly set Assert.Equal(methodSignature.Header, header); Assert.Equal(methodSignature.ReturnType, returnType); Assert.Equal(methodSignature.RequiredParameterCount, requiredParameterCount); Assert.Equal(methodSignature.GenericParameterCount, genericParameterCount); Assert.Equal(methodSignature.ParameterTypes, parameterTypes); }
// TODO: ARe we handling generic methods properly? // TODO: Are we handling explicit-implementation interface methods properly? private static void AddInterfaceMethods( TypeBuilder proxyTB, FieldBuilder mapField, Type superclass, HashSet<Type> allInterfaces, HashSet<MethodBuilder> specialMethods) { HashSet<MethodSignature> considered = new HashSet<MethodSignature>(); List<MethodInfo> implementedMethods = new List<MethodInfo>(); List<MethodInfo> unimplementedMethods = new List<MethodInfo>(); MethodInfo[] minfos = superclass.GetMethods(BindingFlags.Public|BindingFlags.NonPublic| BindingFlags.Instance| BindingFlags.InvokeMethod); foreach (MethodInfo m in minfos ) { MethodSignature sig = new MethodSignature(m); if (!considered.Contains(sig) && !m.IsPrivate && !m.IsStatic && !m.IsFinal) { if (m.IsAbstract) unimplementedMethods.Add(m); else implementedMethods.Add(m); } considered.Add(sig); } foreach ( Type ifType in allInterfaces ) foreach (MethodInfo m in ifType.GetMethods() ) { MethodSignature sig = new MethodSignature(m); if (!considered.Contains(sig)) unimplementedMethods.Add(m); considered.Add(sig); } foreach (MethodInfo m in implementedMethods) GenerateProxyMethod(proxyTB, mapField, m, specialMethods); foreach (MethodInfo m in unimplementedMethods) GenerateProxyMethod(proxyTB, mapField, m, specialMethods); }
/// <summary> /// Initializes a new instance of the <see cref="MethodRunner"/> class. /// </summary> /// <param name="typeRunner">The assembly runner.</param> /// <param name="method">The method.</param> /// <param name="target">The target.</param> /// <param name="methodSignature">The method signature.</param> public MethodRunner(TypeRunner typeRunner, MethodInfo method, object target, MethodSignature methodSignature) { // Check for null arguments. if (typeRunner == null) { throw new ArgumentNullException("typeRunner"); } if (method == null) { throw new ArgumentNullException("method"); } if (target == null) { throw new ArgumentNullException("target"); } // Save the parameters into fields. this.typeRunner = typeRunner; this.method = method; this.target = target; this.methodSignature = methodSignature; }
private MethodSignature InitializeSignature() { var metadataReader = MetadataReader; NativeFormatSignatureParser parser = new NativeFormatSignatureParser(MetadataUnit, MetadataReader.GetMethod(_handle).Signature, metadataReader); var signature = parser.ParseMethodSignature(); return (_signature = signature); }
public static void ThrowMissingMethodException(TypeDesc owningType, string methodName, MethodSignature signature) { throw new TypeSystemException.MissingMethodException(ExceptionStringID.MissingMethod, Format.Method(owningType, methodName, signature)); }
public override void Implement(TransformationContext context) { ModuleDeclaration module = this.AspectWeaver.Module; TypeDefDeclaration typeDef = (TypeDefDeclaration)context.TargetElement; // Declare the method. MethodDefDeclaration methodDef = new MethodDefDeclaration { Name = "AutoGeneratedValidate", Attributes = (MethodAttributes.Family | MethodAttributes.ReuseSlot | MethodAttributes.Virtual), CallingConvention = CallingConvention.HasThis }; typeDef.Methods.Add(methodDef); methodDef.CustomAttributes.Add(this.AspectWeaver.AspectInfrastructureTask.WeavingHelper.GetDebuggerNonUserCodeAttribute()); // Define parameter. methodDef.ReturnParameter = new ParameterDeclaration { ParameterType = module.Cache.GetIntrinsic(IntrinsicType.Void), Attributes = ParameterAttributes.Retval }; // Define the body MethodBodyDeclaration methodBody = new MethodBodyDeclaration(); methodDef.MethodBody = methodBody; InstructionBlock instructionBlock = methodBody.CreateInstructionBlock(); methodBody.RootInstructionBlock = instructionBlock; InstructionSequence sequence = methodBody.CreateInstructionSequence(); instructionBlock.AddInstructionSequence(sequence, NodePosition.After, null); using (InstructionWriter writer = new InstructionWriter()) { writer.AttachInstructionSequence( sequence ); // Find the base method. IMethod baseValidateMethod = null; IType baseTypeCursor = typeDef.BaseType; MethodSignature methodSignature = new MethodSignature( module, CallingConvention.HasThis, module.Cache.GetIntrinsic( IntrinsicType.Void ), new ITypeSignature[0], 0 ); while ( baseValidateMethod == null ) { TypeDefDeclaration baseTypeCursorTypeDef = baseTypeCursor.GetTypeDefinition(); baseValidateMethod = baseTypeCursorTypeDef.Methods.GetMethod( "AutoGeneratedValidate", methodSignature.Translate( baseTypeCursorTypeDef.Module ), BindingOptions.OnlyExisting | BindingOptions.DontThrowException ); baseTypeCursor = baseTypeCursorTypeDef.BaseType; } // TODO: support generic base types. // Call the base method. writer.EmitInstruction( OpCodeNumber.Ldarg_0 ); writer.EmitInstructionMethod( OpCodeNumber.Call, (IMethod) baseValidateMethod.Translate( typeDef.Module ) ); // Make an array with the boxed field values. TypeValidationAspect aspect = (TypeValidationAspect) this.AspectWeaverInstance.Aspect; LocalVariableSymbol fieldValuesArrayLocal = instructionBlock.DefineLocalVariable( module.Cache.GetType( typeof(object[]) ), "fieldValues" ); writer.EmitInstructionInt32( OpCodeNumber.Ldc_I4, aspect.Validators.Count ); writer.EmitInstructionType( OpCodeNumber.Newarr, module.Cache.GetIntrinsic( IntrinsicType.Object ) ); writer.EmitInstructionLocalVariable( OpCodeNumber.Stloc, fieldValuesArrayLocal ); int i = 0; foreach ( FieldValidationAttribute validator in aspect.Validators ) { FieldDefDeclaration fieldDef = typeDef.Fields.GetByName( validator.TargetLocation.Name ); IField fieldSpec = GenericHelper.GetFieldCanonicalGenericInstance( fieldDef ); writer.EmitInstructionLocalVariable( OpCodeNumber.Ldloc, fieldValuesArrayLocal ); writer.EmitInstructionInt32( OpCodeNumber.Ldc_I4, i ); writer.EmitInstruction( OpCodeNumber.Ldarg_0 ); writer.EmitInstructionField( OpCodeNumber.Ldfld, fieldSpec ); writer.EmitConvertToObject( fieldSpec.FieldType ); writer.EmitInstruction( OpCodeNumber.Stelem_Ref ); i++; } // Get the validator method. IMethod validateMethod = module.Cache.GetItem( () => module.FindMethod( typeof(TypeValidationAspect).GetMethod( "Validate" ), BindingOptions.Default ) ); // Call the validator. this.AspectWeaverInstance.AspectRuntimeInstanceField.EmitLoadField( writer, null ); writer.EmitInstructionLocalVariable( OpCodeNumber.Ldloc, fieldValuesArrayLocal ); writer.EmitInstructionMethod( OpCodeNumber.Callvirt, validateMethod ); writer.EmitInstruction( OpCodeNumber.Ret ); writer.DetachInstructionSequence(); } }
public ILToken NewToken(MethodSignature value) { return(NewToken(value, 0x11000000)); }
public static TypeDesc[] GetThunkInstantiationForMethod(MethodDesc method) { MethodSignature sig = method.Signature; ParameterMetadata[] paramMetadata = null; TypeDesc[] instantiation = new TypeDesc[sig.ReturnType.IsVoid ? sig.Length : sig.Length + 1]; for (int i = 0; i < sig.Length; i++) { TypeDesc parameterType = sig[i]; if (parameterType.IsByRef) { // strip ByRefType off the parameter (the method already has ByRef in the signature) parameterType = ((ByRefType)parameterType).ParameterType; // Strip off all the pointers. Pointers are not valid instantiation arguments and the thunk compensates for that // by being specialized for the specific pointer depth. while (parameterType.IsPointer) { parameterType = ((PointerType)parameterType).ParameterType; } } else if (parameterType.IsPointer) { // Strip off all the pointers. Pointers are not valid instantiation arguments and the thunk compensates for that // by being specialized for the specific pointer depth. while (parameterType.IsPointer) { parameterType = ((PointerType)parameterType).ParameterType; } } else if (parameterType.IsEnum) { // If the invoke method takes an enum as an input parameter and there is no default value for // that paramter, we don't need to specialize on the exact enum type (we only need to specialize // on the underlying integral type of the enum.) if (paramMetadata == null) { paramMetadata = method.GetParameterMetadata(); } bool hasDefaultValue = false; foreach (var p in paramMetadata) { // Parameter metadata indexes are 1-based (0 is reserved for return "parameter") if (p.Index == (i + 1) && p.HasDefault) { hasDefaultValue = true; break; } } if (!hasDefaultValue) { parameterType = parameterType.UnderlyingType; } } instantiation[i] = parameterType; } if (!sig.ReturnType.IsVoid) { TypeDesc returnType = sig.ReturnType; // strip ByRefType off the return type (the method already has ByRef in the signature) if (returnType.IsByRef) { returnType = ((ByRefType)returnType).ParameterType; } // If the invoke method return an object reference, we don't need to specialize on the // exact type of the object reference, as the behavior is not different. if ((returnType.IsDefType && !returnType.IsValueType) || returnType.IsArray) { returnType = method.Context.GetWellKnownType(WellKnownType.Object); } // Strip off all the pointers. Pointers are not valid instantiation arguments and the thunk compensates for that // by being specialized for the specific pointer depth. while (returnType.IsPointer) { returnType = ((PointerType)returnType).ParameterType; } instantiation[sig.Length] = returnType; } return(instantiation); }
internal DelegateThunkCollection(DelegateInfo owningDelegate) { _openStaticThunk = new DelegateInvokeOpenStaticThunk(owningDelegate); _multicastThunk = new DelegateInvokeMulticastThunk(owningDelegate); _closedStaticThunk = new DelegateInvokeClosedStaticThunk(owningDelegate); _closedInstanceOverGeneric = new DelegateInvokeInstanceClosedOverGenericMethodThunk(owningDelegate); // Methods that have a byref-like type in the signature cannot be invoked with the object array thunk. // We would need to box the parameter and these can't be boxed. // Neither can be methods that have pointers in the signature. MethodSignature delegateSignature = owningDelegate.Signature; bool generateObjectArrayThunk = true; for (int i = 0; i < delegateSignature.Length; i++) { TypeDesc paramType = delegateSignature[i]; if (paramType.IsByRef) { paramType = ((ByRefType)paramType).ParameterType; } if (!paramType.IsSignatureVariable && paramType.IsByRefLike) { generateObjectArrayThunk = false; break; } if (paramType.IsPointer || paramType.IsFunctionPointer) { generateObjectArrayThunk = false; break; } } TypeDesc normalizedReturnType = delegateSignature.ReturnType; if (normalizedReturnType.IsByRef) { normalizedReturnType = ((ByRefType)normalizedReturnType).ParameterType; } if (!normalizedReturnType.IsSignatureVariable && normalizedReturnType.IsByRefLike) { generateObjectArrayThunk = false; } if (normalizedReturnType.IsPointer || normalizedReturnType.IsFunctionPointer) { generateObjectArrayThunk = false; } if ((owningDelegate.SupportedFeatures & DelegateFeature.ObjectArrayThunk) != 0 && generateObjectArrayThunk) { _invokeObjectArrayThunk = new DelegateInvokeObjectArrayThunk(owningDelegate); } // // Check whether we have a reverse p/invoke thunk // if (!owningDelegate.Type.HasInstantiation && IsNativeCallingConventionCompatible(delegateSignature)) { _reversePInvokeThunk = new DelegateReversePInvokeThunk(owningDelegate); } // // Check whether we have an open instance thunk // if (delegateSignature.Length > 0) { TypeDesc firstParam = delegateSignature[0]; bool generateOpenInstanceMethod; switch (firstParam.Category) { case TypeFlags.Pointer: case TypeFlags.FunctionPointer: generateOpenInstanceMethod = false; break; case TypeFlags.ByRef: firstParam = ((ByRefType)firstParam).ParameterType; generateOpenInstanceMethod = firstParam.IsSignatureVariable || firstParam.IsValueType; break; case TypeFlags.Array: case TypeFlags.SzArray: case TypeFlags.SignatureTypeVariable: generateOpenInstanceMethod = true; break; default: Debug.Assert(firstParam.IsDefType); generateOpenInstanceMethod = !firstParam.IsValueType; break; } if (generateOpenInstanceMethod) { _openInstanceThunk = new DelegateInvokeOpenInstanceThunk(owningDelegate); } } }
static string OverloadName(MethodSignature sig) { if ( sig.ParamTypes.Length == 0 ) return sig.Name + "-void"; else { string[] names = new string[sig.ParamTypes.Length+1]; names[0] = sig.Name; for ( int i=0; i< sig.ParamTypes.Length; i++ ) names[i+1] = EscapeTypeName(sig.ParamTypes[i]); return String.Join("-",names); } }
public MethodDesc GetCalliStub(MethodSignature signature) { return(_interopStateManager.GetPInvokeCalliStub(signature)); }
public MethodSignatureFilter(ResolveErrorType errorType, MethodSignature methodSignature) { myMethodSignature = methodSignature; ErrorType = errorType; }
private MemberInfo GetMemberRef(int index, Type[] genericTypeArguments, Type[] genericMethodArguments) { if (memberRefs == null) { memberRefs = new MemberInfo[MemberRef.records.Length]; } if (memberRefs[index] == null) { int owner = MemberRef.records[index].Class; int sig = MemberRef.records[index].Signature; string name = GetString(MemberRef.records[index].Name); switch (owner >> 24) { case MethodDefTable.Index: return(GetMethodAt(null, (owner & 0xFFFFFF) - 1)); case ModuleRefTable.Index: memberRefs[index] = ResolveTypeMemberRef(ResolveModuleType(owner), name, ByteReader.FromBlob(blobHeap, sig)); break; case TypeDefTable.Index: case TypeRefTable.Index: memberRefs[index] = ResolveTypeMemberRef(ResolveType(owner), name, ByteReader.FromBlob(blobHeap, sig)); break; case TypeSpecTable.Index: { Type type = ResolveType(owner, genericTypeArguments, genericMethodArguments); if (type.IsArray) { MethodSignature methodSig = MethodSignature.ReadSig(this, ByteReader.FromBlob(blobHeap, sig), new GenericContext(genericTypeArguments, genericMethodArguments)); return(type.FindMethod(name, methodSig) ?? universe.GetMissingMethodOrThrow(type, name, methodSig)); } else if (type.IsConstructedGenericType) { MemberInfo member = ResolveTypeMemberRef(type.GetGenericTypeDefinition(), name, ByteReader.FromBlob(blobHeap, sig)); MethodBase mb = member as MethodBase; if (mb != null) { member = mb.BindTypeParameters(type); } FieldInfo fi = member as FieldInfo; if (fi != null) { member = fi.BindTypeParameters(type); } return(member); } else { return(ResolveTypeMemberRef(type, name, ByteReader.FromBlob(blobHeap, sig))); } } default: throw new BadImageFormatException(); } } return(memberRefs[index]); }
public MethodIL EmitIL() { MethodSignature targetMethodSignature = _targetMethod.Signature; // We have 4 code streams: // - _marshallingCodeStream is used to convert each argument into a native type and // store that into the local // - callsiteSetupCodeStream is used to used to load each previously generated local // and call the actual target native method. // - _returnValueMarshallingCodeStream is used to convert the native return value // to managed one. // - _unmarshallingCodestream is used to propagate [out] native arguments values to // managed ones. _emitter = new ILEmitter(); ILCodeStream fnptrLoadStream = _emitter.NewCodeStream(); _marshallingCodeStream = _emitter.NewCodeStream(); ILCodeStream callsiteSetupCodeStream = _emitter.NewCodeStream(); _returnValueMarshallingCodeStream = _emitter.NewCodeStream(); _unmarshallingCodestream = _emitter.NewCodeStream(); TypeDesc[] nativeParameterTypes = new TypeDesc[targetMethodSignature.Length]; // // Parameter marshalling // // // Convert each argument to something we can pass to native and store it in a local. // Then load the local in the second code stream. // for (int i = 0; i < targetMethodSignature.Length; i++) { // TODO: throw if there's custom marshalling _marshallingCodeStream.EmitLdArg(i); TypeDesc nativeType = MarshalArgument(targetMethodSignature[i]); nativeParameterTypes[i] = nativeType; ILLocalVariable vMarshalledTypeTemp = _emitter.NewLocal(nativeType); _marshallingCodeStream.EmitStLoc(vMarshalledTypeTemp); callsiteSetupCodeStream.EmitLdLoc(vMarshalledTypeTemp); } // // Return value marshalling // // TODO: throw if SetLastError is true // TODO: throw if there's custom marshalling TypeDesc nativeReturnType = MarshalReturnValue(targetMethodSignature.ReturnType); if (UseLazyResolution(_targetMethod, _importMetadata.Module)) { MetadataType lazyHelperType = _targetMethod.Context.GetHelperType("InteropHelpers"); FieldDesc lazyDispatchCell = new PInvokeLazyFixupField((DefType)_targetMethod.OwningType, _importMetadata); fnptrLoadStream.Emit(ILOpcode.ldsflda, _emitter.NewToken(lazyDispatchCell)); fnptrLoadStream.Emit(ILOpcode.call, _emitter.NewToken(lazyHelperType.GetKnownMethod("ResolvePInvoke", null))); MethodSignatureFlags unmanagedCallConv = PInvokeMetadata.GetUnmanagedCallingConvention(_importMetadata.Attributes); MethodSignature nativeCalliSig = new MethodSignature( targetMethodSignature.Flags | unmanagedCallConv, 0, nativeReturnType, nativeParameterTypes); ILLocalVariable vNativeFunctionPointer = _emitter.NewLocal(_targetMethod.Context.GetWellKnownType(WellKnownType.IntPtr)); fnptrLoadStream.EmitStLoc(vNativeFunctionPointer); callsiteSetupCodeStream.EmitLdLoc(vNativeFunctionPointer); callsiteSetupCodeStream.Emit(ILOpcode.calli, _emitter.NewToken(nativeCalliSig)); } else { // Eager call PInvokeMetadata nativeImportMetadata = new PInvokeMetadata(_importMetadata.Module, _importMetadata.Name ?? _targetMethod.Name, _importMetadata.Attributes); MethodSignature nativeSig = new MethodSignature( targetMethodSignature.Flags, 0, nativeReturnType, nativeParameterTypes); MethodDesc nativeMethod = new PInvokeTargetNativeMethod(_targetMethod.OwningType, nativeSig, nativeImportMetadata); callsiteSetupCodeStream.Emit(ILOpcode.call, _emitter.NewToken(nativeMethod)); } _unmarshallingCodestream.Emit(ILOpcode.ret); return(_emitter.Link(_targetMethod)); }
internal static (IType returnType, IParameter[] parameters, ModifiedType returnTypeModifier) DecodeSignature( MetadataModule module, IParameterizedMember owner, MethodSignature <IType> signature, ParameterHandleCollection?parameterHandles, Nullability nullableContext, TypeSystemOptions typeSystemOptions, CustomAttributeHandleCollection?returnTypeAttributes = null) { var metadata = module.metadata; int i = 0; IParameter[] parameters = new IParameter[signature.RequiredParameterCount + (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs ? 1 : 0)]; IType parameterType; if (parameterHandles != null) { foreach (var parameterHandle in parameterHandles) { var par = metadata.GetParameter(parameterHandle); if (par.SequenceNumber == 0) { // "parameter" holds return type attributes. // Note: for properties, the attributes normally stored on a method's return type // are instead stored as normal attributes on the property. // So MetadataProperty provides a non-null value for returnTypeAttributes, // which then should be preferred over the attributes on the accessor's parameters. if (returnTypeAttributes == null) { returnTypeAttributes = par.GetCustomAttributes(); } } else if (i < par.SequenceNumber && par.SequenceNumber <= signature.RequiredParameterCount) { // "Successive rows of the Param table that are owned by the same method shall be // ordered by increasing Sequence value - although gaps in the sequence are allowed" Debug.Assert(par.SequenceNumber <= signature.ParameterTypes.Length); Debug.Assert(par.SequenceNumber <= parameters.Length); // Fill gaps in the sequence with non-metadata parameters: while (i < par.SequenceNumber - 1) { parameterType = ApplyAttributeTypeVisitor.ApplyAttributesToType( signature.ParameterTypes[i], module.Compilation, null, metadata, typeSystemOptions, nullableContext); parameters[i] = new DefaultParameter(parameterType, name: string.Empty, owner, referenceKind: parameterType.Kind == TypeKind.ByReference ? ReferenceKind.Ref : ReferenceKind.None); i++; } parameterType = ApplyAttributeTypeVisitor.ApplyAttributesToType( signature.ParameterTypes[i], module.Compilation, par.GetCustomAttributes(), metadata, typeSystemOptions, nullableContext); parameters[i] = new MetadataParameter(module, owner, parameterType, parameterHandle); i++; } } } while (i < signature.RequiredParameterCount) { parameterType = ApplyAttributeTypeVisitor.ApplyAttributesToType( signature.ParameterTypes[i], module.Compilation, null, metadata, typeSystemOptions, nullableContext); parameters[i] = new DefaultParameter(parameterType, name: string.Empty, owner, referenceKind: parameterType.Kind == TypeKind.ByReference ? ReferenceKind.Ref : ReferenceKind.None); i++; } if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) { parameters[i] = new DefaultParameter(SpecialType.ArgList, name: string.Empty, owner); i++; } Debug.Assert(i == parameters.Length); var returnType = ApplyAttributeTypeVisitor.ApplyAttributesToType(signature.ReturnType, module.Compilation, returnTypeAttributes, metadata, typeSystemOptions, nullableContext, isSignatureReturnType: true); return(returnType, parameters, signature.ReturnType as ModifiedType); }
//------------------------------------------------------------------------------------------------------------------------------------------------- public LogMethodWriter(TemplateMethodWriter underlyingWriter, Field<IThreadLogAppender> threadLogAppenderField) { _underlyingWriter = underlyingWriter; _threadLogAppenderField = threadLogAppenderField; _declaration = underlyingWriter.OwnerMethod.MethodDeclaration; _signature = underlyingWriter.OwnerMethod.Signature; _parameters = _declaration.GetParameters(); _messageId = GetMessageId(_declaration); _attribute = _declaration.GetCustomAttribute<LogAttributeBase>(); _mustCreateException = _declaration.ReturnType.IsExceptionType(); _exceptionArgumentIndex = new List<int>(); _isValueArgument = new bool[_signature.ArgumentCount]; _valueArgumentFormat = new string[_signature.ArgumentCount]; _valueArgumentDetails = new DetailAttribute[_signature.ArgumentCount]; _nameValuePairLocals = new List<IOperand>(); ValidateSignature(); }
private string GetMethodTypeName(MethodSignature method) { var containingTypeName = method.ContainingType.TypeName.Split('.').Last(); return(string.Concat(containingTypeName, ".", method.Name)); }
private static void GetAllMethods(Type type, HashSet<MethodSignature> considered, List<MethodSignature> todo, string source) { foreach (MethodInfo mi in type.GetMethods(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)) { MethodSignature ms = new MethodSignature(mi, source); if (!considered.Contains(ms) && (mi.IsPublic || mi.IsFamily) && !mi.IsStatic && !mi.IsFinal && !"Dispose".Equals(mi.Name)) todo.Add(ms); considered.Add(ms); } }
public DummyType GetFunctionPointerType(MethodSignature <DummyType> signature) { return(DummyType.Instance); }
GetParameters(MetadataReader reader, TypeReferenceTypeProvider typeProvider, GenericContext genericContext, MethodSignature <MetadataTypeReference> signature, ParameterHandleCollection handles) { var parameters = new IMetadataParameter[handles.Count]; var returnValueAttributes = (IReadOnlyList <IMetadataAttribute>)null; var maxSequenceNumber = 0; foreach (var handle in handles) { var parameter = reader.GetParameter(handle); if (parameter.SequenceNumber == 0) { returnValueAttributes = GetAttributes(reader, typeProvider, parameter.GetCustomAttributes(), genericContext); continue; } if (maxSequenceNumber < parameter.SequenceNumber) { maxSequenceNumber = parameter.SequenceNumber; } var parameterIndex = parameter.SequenceNumber - 1; parameters[parameterIndex] = new ReaderParameter(reader, typeProvider, parameter, genericContext, signature.ParameterTypes[parameterIndex]); } if (maxSequenceNumber == parameters.Length) { return(parameters, Array.Empty <IMetadataAttribute>()); } // Account for skipping the return parameter var correctedLength = new IMetadataParameter[maxSequenceNumber]; Array.Copy(parameters, correctedLength, correctedLength.Length); return(correctedLength, returnValueAttributes); }
public IHtmlString Render(MethodSignature method, MethodRenderOption option) { return(_methodRenderer.Render(_languageProvider, method, option)); }
public PInvokeTargetNativeMethod(MethodDesc declMethod, MethodSignature signature) { _declMethod = declMethod; _signature = signature; }
/// <summary> /// Compute the canonical instantiation of a dynamic invoke thunk needed to invoke a method /// This algorithm is shared with the runtime, so if a thunk requires generic instantiation /// to be used, it must match this algorithm, and cannot be different with different MetadataManagers /// NOTE: This function may return null in cases where an exact instantiation does not exist. (Universal Generics) /// </summary> protected MethodDesc InstantiateCanonicalDynamicInvokeMethodForMethod(MethodDesc thunk, MethodDesc method) { if (thunk.Instantiation.Length == 0) { // nothing to instantiate return(thunk); } MethodSignature sig = method.Signature; TypeSystemContext context = method.Context; // // Instantiate the generic thunk over the parameters and the return type of the target method // ParameterMetadata[] paramMetadata = null; TypeDesc[] instantiation = new TypeDesc[sig.ReturnType.IsVoid ? sig.Length : sig.Length + 1]; Debug.Assert(thunk.Instantiation.Length == instantiation.Length); for (int i = 0; i < sig.Length; i++) { TypeDesc parameterType = sig[i]; if (parameterType.IsByRef) { // strip ByRefType off the parameter (the method already has ByRef in the signature) parameterType = ((ByRefType)parameterType).ParameterType; Debug.Assert(!parameterType.IsPointer); // TODO: support for methods returning pointer types - https://github.com/dotnet/corert/issues/2113 } else if (parameterType.IsPointer || parameterType.IsFunctionPointer) { // For pointer typed parameters, instantiate the method over IntPtr parameterType = context.GetWellKnownType(WellKnownType.IntPtr); } else if (parameterType.IsEnum) { // If the invoke method takes an enum as an input parameter and there is no default value for // that paramter, we don't need to specialize on the exact enum type (we only need to specialize // on the underlying integral type of the enum.) if (paramMetadata == null) { paramMetadata = method.GetParameterMetadata(); } bool hasDefaultValue = false; foreach (var p in paramMetadata) { // Parameter metadata indexes are 1-based (0 is reserved for return "parameter") if (p.Index == (i + 1) && p.HasDefault) { hasDefaultValue = true; break; } } if (!hasDefaultValue) { parameterType = parameterType.UnderlyingType; } } instantiation[i] = parameterType; } if (!sig.ReturnType.IsVoid) { TypeDesc returnType = sig.ReturnType; Debug.Assert(!returnType.IsByRef); // If the invoke method return an object reference, we don't need to specialize on the // exact type of the object reference, as the behavior is not different. if ((returnType.IsDefType && !returnType.IsValueType) || returnType.IsArray) { returnType = context.GetWellKnownType(WellKnownType.Object); } instantiation[sig.Length] = returnType; } Debug.Assert(thunk.Instantiation.Length == instantiation.Length); // Check if at least one of the instantiation arguments is a universal canonical type, and if so, we // won't create a dynamic invoker instantiation. The arguments will be interpreted at runtime by the // calling convention converter during the dynamic invocation foreach (TypeDesc type in instantiation) { if (type.IsCanonicalSubtype(CanonicalFormKind.Universal)) { return(null); } } // If the thunk ends up being shared code, return the canonical method body. // The concrete dictionary for the thunk will be built at runtime and is not interesting for the compiler. Instantiation canonInstantiation = context.ConvertInstantiationToCanonForm(new Instantiation(instantiation), CanonicalFormKind.Specific); MethodDesc instantiatedDynamicInvokeMethod = thunk.Context.GetInstantiatedMethod(thunk, canonInstantiation); return(instantiatedDynamicInvokeMethod); }
private Object ResolveMemberReference(MemberReferenceHandle handle) { MemberReference memberReference = _metadataReader.GetMemberReference(handle); Object parent = GetObject(memberReference.Parent); TypeDesc parentTypeDesc = parent as TypeDesc; if (parentTypeDesc != null) { BlobReader signatureReader = _metadataReader.GetBlobReader(memberReference.Signature); EcmaSignatureParser parser = new EcmaSignatureParser(this, signatureReader); string name = _metadataReader.GetString(memberReference.Name); if (parser.IsFieldSignature) { FieldDesc field = parentTypeDesc.GetField(name); if (field != null) { return(field); } // TODO: Better error message throw new MissingMemberException("Field not found " + parent.ToString() + "." + name); } else { MethodSignature sig = parser.ParseMethodSignature(); TypeDesc typeDescToInspect = parentTypeDesc; // Try to resolve the name and signature in the current type, or any of the base types. do { // TODO: handle substitutions MethodDesc method = typeDescToInspect.GetMethod(name, sig); if (method != null) { // If this resolved to one of the base types, make sure it's not a constructor. // Instance constructors are not inherited. if (typeDescToInspect != parentTypeDesc && method.IsConstructor) { break; } return(method); } typeDescToInspect = typeDescToInspect.BaseType; } while (typeDescToInspect != null); // TODO: Better error message throw new MissingMemberException("Method not found " + parent.ToString() + "." + name); } } else if (parent is MethodDesc) { throw new NotSupportedException("Vararg methods not supported in .NET Core."); } else if (parent is ModuleDesc) { throw new NotImplementedException("MemberRef to a global function or variable."); } throw new BadImageFormatException(); }
public InvokableMethod(Delegate invokableMethod, MethodSignature signature) { Debug.Assert(invokableMethod != null); this.invokableMethod = invokableMethod; this.signature = signature; }
public EventDef(IImSeq<Annotation> annotations, ISeq<CustomAttribute> customAttributes, string name, bool isStatic, MethodSignature add, MethodSignature remove, TypeRef handlerType) : base(annotations, customAttributes, name, isStatic) { Add = add; Remove = remove; HandlerType = handlerType; }
/// <summary> /// Builds the name of the method. /// </summary> /// <param name="info">The method information.</param> /// <returns>The method name.</returns> private static string BuildMethodName(MethodBase info) => MethodSignature.FormatWith( info.DeclaringType?.Name, info.Name, info.GetParameters().Select(x => ParameterName.FormatWith(x.ParameterType.Name, x.Name)).ToCommaSeparatedString());
public void GetCallRefMap(MethodDesc method, bool isUnboxingStub) { TransitionBlock transitionBlock = TransitionBlock.FromTarget(method.Context.Target); MethodSignature signature = method.Signature; bool hasThis = (signature.Flags & MethodSignatureFlags.Static) == 0; // This pointer is omitted for string constructors bool fCtorOfVariableSizedObject = hasThis && method.OwningType.IsString && method.IsConstructor; if (fCtorOfVariableSizedObject) { hasThis = false; } bool isVarArg = false; TypeHandle returnType = new TypeHandle(signature.ReturnType); TypeHandle[] parameterTypes = new TypeHandle[signature.Length]; for (int parameterIndex = 0; parameterIndex < parameterTypes.Length; parameterIndex++) { parameterTypes[parameterIndex] = new TypeHandle(signature[parameterIndex]); } CallingConventions callingConventions = (hasThis ? CallingConventions.ManagedInstance : CallingConventions.ManagedStatic); bool hasParamType = method.RequiresInstArg() && !isUnboxingStub; // On X86 the Array address method doesn't use IL stubs, and instead has a custom calling convention if ((method.Context.Target.Architecture == TargetArchitecture.X86) && method.IsArrayAddressMethod()) { hasParamType = true; } bool extraFunctionPointerArg = false; bool[] forcedByRefParams = new bool[parameterTypes.Length]; bool skipFirstArg = false; bool extraObjectFirstArg = false; ArgIteratorData argIteratorData = new ArgIteratorData(hasThis, isVarArg, parameterTypes, returnType); ArgIterator argit = new ArgIterator( method.Context, argIteratorData, callingConventions, hasParamType, extraFunctionPointerArg, forcedByRefParams, skipFirstArg, extraObjectFirstArg); int nStackBytes = argit.SizeOfFrameArgumentArray(); // Allocate a fake stack CORCOMPILE_GCREFMAP_TOKENS[] fakeStack = new CORCOMPILE_GCREFMAP_TOKENS[transitionBlock.SizeOfTransitionBlock + nStackBytes]; // Fill it in FakeGcScanRoots(method, argit, fakeStack, isUnboxingStub); // Encode the ref map uint nStackSlots; if (_target.Architecture == TargetArchitecture.X86) { uint cbStackPop = argit.CbStackPop(); WriteStackPop(cbStackPop / (uint)_target.PointerSize); nStackSlots = (uint)(nStackBytes / _target.PointerSize + _transitionBlock.NumArgumentRegisters); } else { nStackSlots = (uint)((transitionBlock.SizeOfTransitionBlock + nStackBytes - _transitionBlock.OffsetOfFirstGCRefMapSlot) / _target.PointerSize); } for (uint pos = 0; pos < nStackSlots; pos++) { int offset = _transitionBlock.OffsetFromGCRefMapPos(checked ((int)pos)); CORCOMPILE_GCREFMAP_TOKENS token = fakeStack[offset]; if (token != CORCOMPILE_GCREFMAP_TOKENS.GCREFMAP_SKIP) { WriteToken(pos, (byte)token); } } Flush(); }
public MethodIL EmitIL() { // We have two code streams - one is used to convert each argument into a native type // and store that into the local. The other is used to load each previously generated local // and call the actual target native method. _emitter = new ILEmitter(); _marshallingCodeStream = _emitter.NewCodeStream(); ILCodeStream callsiteSetupCodeStream = _emitter.NewCodeStream(); // TODO: throw if SetLastError is true // TODO: throw if there's custom marshalling TypeDesc nativeReturnType = _targetMethod.Signature.ReturnType; if (!IsBlittableType(nativeReturnType) && !nativeReturnType.IsVoid) { throw new NotSupportedException(); } TypeDesc[] nativeParameterTypes = new TypeDesc[_targetMethod.Signature.Length]; // // Convert each argument to something we can pass to native and store it in a local. // Then load the local in the second code stream. // for (int i = 0; i < _targetMethod.Signature.Length; i++) { // TODO: throw if there's custom marshalling TypeDesc parameterType = _targetMethod.Signature[i]; _marshallingCodeStream.EmitLdArg(i); TypeDesc nativeType; if (parameterType.IsSzArray) { nativeType = EmitArrayMarshalling((ArrayType)parameterType); } else if (parameterType.IsByRef) { nativeType = EmitByRefMarshalling((ByRefType)parameterType); } else if (parameterType.IsString) { nativeType = EmitStringMarshalling(); } else { if (!IsBlittableType(parameterType)) { throw new NotSupportedException(); } nativeType = parameterType.UnderlyingType; } nativeParameterTypes[i] = nativeType; ILLocalVariable vMarshalledTypeTemp = _emitter.NewLocal(nativeType); _marshallingCodeStream.EmitStLoc(vMarshalledTypeTemp); callsiteSetupCodeStream.EmitLdLoc(vMarshalledTypeTemp); } MethodSignature nativeSig = new MethodSignature( _targetMethod.Signature.Flags, 0, nativeReturnType, nativeParameterTypes); MethodDesc nativeMethod = new PInvokeTargetNativeMethod(_targetMethod.OwningType, nativeSig, _importMetadata); // Call the native method callsiteSetupCodeStream.Emit(ILOpcode.call, _emitter.NewToken(nativeMethod)); callsiteSetupCodeStream.Emit(ILOpcode.ret); return(_emitter.Link()); }
private InterceptorState FindInterceptorStateByMethodSignature(MethodSignature signature) { return InterceptorStateCollection.Where(m => m.MethodSignature.Equals(signature)).SingleOrDefault(); }
public PInvokeTargetNativeMethod(TypeDesc owningType, MethodSignature signature, PInvokeMetadata methodMetadata) { _owningType = owningType; _signature = signature; _methodMetadata = methodMetadata; }
// TODO: Define an extension to proxy that allows overriding getters/setters on properties. private static void AddInterfaceProperties( TypeBuilder proxyTB, Type superclass, HashSet<Type> allInterfaces, HashSet<MethodBuilder> specialMethods) { HashSet<MethodSignature> considered = new HashSet<MethodSignature>(); List<PropertyInfo> properties = new List<PropertyInfo>(); PropertyInfo[] pinfos = superclass.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (PropertyInfo p in pinfos) { MethodSignature sig = new MethodSignature(p); if (!considered.Contains(sig)) properties.Add(p); considered.Add(sig); } foreach (Type ifType in allInterfaces) foreach (PropertyInfo p in ifType.GetProperties()) { MethodSignature sig = new MethodSignature(p); if (!considered.Contains(sig)) properties.Add(p); considered.Add(sig); } foreach (PropertyInfo pi in properties) { PropertyBuilder pb = proxyTB.DefineProperty(pi.Name, pi.Attributes, pi.PropertyType, pi.GetIndexParameters().Select<ParameterInfo, Type>(p => p.ParameterType).ToArray<Type>()); string getterName = "get_" + pi.Name; string setterName = "set_" + pi.Name; MethodBuilder getter = specialMethods.Where(m => m.Name.Equals(getterName)).FirstOrDefault(); MethodBuilder setter = specialMethods.Where(m => m.Name.Equals(setterName)).FirstOrDefault(); if ( getter != null ) pb.SetGetMethod(getter); if ( setter != null ) pb.SetSetMethod(setter); //Console.Write("Generating proxy property {0} ({1})", pi.Name, pi.PropertyType); //if (getter != null) // Console.Write(", get = {0}", getter.Name); //if (setter != null) // Console.Write(", set = {0}", setter.Name); //Console.WriteLine(); } }
private static void EmitForwardingMethod(TypeBuilder proxyTB, bool isStatic, FieldBuilder regularFB, FieldBuilder overloadFB, MethodSignature sig, ElseGenDelegate elseGen) { MethodAttributes attributes; CallingConventions conventions; if (isStatic) { attributes = MethodAttributes.Public | MethodAttributes.Static; conventions = CallingConventions.Standard; } else { attributes = MethodAttributes.Public | MethodAttributes.Virtual; conventions = CallingConventions.HasThis; } MethodBuilder mb = proxyTB.DefineMethod(sig.Name, attributes, conventions, sig.ReturnType, sig.ParamTypes); CljILGen gen = new CljILGen(mb.GetILGenerator()); Label foundLabel = gen.DefineLabel(); Label elseLabel = gen.DefineLabel(); Label endLabel = gen.DefineLabel(); if (sig.ParamTypes.Length > 18) { elseGen(gen); } else { if (overloadFB != null) { EmitGetVar(gen, overloadFB); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Brtrue_S, foundLabel); gen.Emit(OpCodes.Pop); } EmitGetVar(gen, regularFB); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Brfalse_S, elseLabel); if (overloadFB != null) { gen.MarkLabel(foundLabel); } gen.Emit(OpCodes.Castclass, typeof(IFn)); if (!isStatic) { gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0); } for (int i = 0; i < sig.ParamTypes.Length; i++) { gen.EmitLoadArg(isStatic ? i : i + 1); // gen.Emit(OpCodes.Ldarg, i + 1); if (sig.ParamTypes[i].IsValueType) { gen.Emit(OpCodes.Box, sig.ParamTypes[i]); } } gen.EmitCall(Compiler.Methods_IFn_invoke[sig.ParamTypes.Length + (isStatic ? 0 : 1)]); //gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[sig.ParamTypes.Length + (isStatic ? 0 : 1)]); if (sig.ReturnType == typeof(void)) { gen.Emit(OpCodes.Pop); } else if (sig.ReturnType.IsValueType) { gen.Emit(OpCodes.Unbox_Any, sig.ReturnType); } else { gen.Emit(OpCodes.Castclass, sig.ReturnType); } gen.Emit(OpCodes.Br_S, endLabel); gen.MarkLabel(elseLabel); gen.Emit(OpCodes.Pop); elseGen(gen); gen.MarkLabel(endLabel); gen.Emit(OpCodes.Ret); } }
private static void EmitForwardingMethod(TypeBuilder proxyTB, bool isStatic, FieldBuilder regularFB, FieldBuilder overloadFB, MethodSignature sig, ElseGenDelegate elseGen) { MethodAttributes attributes; CallingConventions conventions; if (isStatic) { attributes = MethodAttributes.Public | MethodAttributes.Static; conventions = CallingConventions.Standard; } else { attributes = MethodAttributes.Public | MethodAttributes.Virtual; conventions = CallingConventions.HasThis; } MethodBuilder mb = proxyTB.DefineMethod(sig.Name, attributes, conventions, sig.ReturnType, sig.ParamTypes); ILGen gen = new ILGen(mb.GetILGenerator()); Label foundLabel = gen.DefineLabel(); Label elseLabel = gen.DefineLabel(); Label endLabel = gen.DefineLabel(); if (sig.ParamTypes.Length > 18) elseGen(gen); else { if (overloadFB != null) { EmitGetVar(gen, overloadFB); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Brtrue_S, foundLabel); gen.Emit(OpCodes.Pop); } EmitGetVar(gen, regularFB); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Brfalse_S, elseLabel); if (overloadFB != null) gen.MarkLabel(foundLabel); gen.Emit(OpCodes.Castclass, typeof(IFn)); if (!isStatic) gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0); for (int i = 0; i < sig.ParamTypes.Length; i++) { gen.EmitLoadArg(isStatic ? i : i + 1); // gen.Emit(OpCodes.Ldarg, i + 1); if (sig.ParamTypes[i].IsValueType) gen.Emit(OpCodes.Box, sig.ParamTypes[i]); } gen.EmitCall(Compiler.Methods_IFn_invoke[sig.ParamTypes.Length + (isStatic ? 0 : 1)]); //gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[sig.ParamTypes.Length + (isStatic ? 0 : 1)]); if (sig.ReturnType == typeof(void)) gen.Emit(OpCodes.Pop); else if (sig.ReturnType.IsValueType) gen.Emit(OpCodes.Unbox_Any,sig.ReturnType); gen.Emit(OpCodes.Br_S, endLabel); gen.MarkLabel(elseLabel); gen.Emit(OpCodes.Pop); elseGen(gen); gen.MarkLabel(endLabel); gen.Emit(OpCodes.Ret); } }
public void SimpleSignatureProviderCoverage() { using (FileStream stream = File.OpenRead(typeof(SignaturesToDecode <>).GetTypeInfo().Assembly.Location)) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); var provider = new DisassemblingTypeProvider(); TypeDefinitionHandle typeHandle = TestMetadataResolver.FindTestType(reader, typeof(SignaturesToDecode <>)); Assert.Equal("System.Reflection.Metadata.Decoding.Tests.SignatureDecoderTests/SignaturesToDecode`1", provider.GetTypeFromHandle(reader, genericContext: null, handle: typeHandle)); TypeDefinition type = reader.GetTypeDefinition(typeHandle); Dictionary <string, string> expectedFields = GetExpectedFieldSignatures(); ImmutableArray <string> genericTypeParameters = type.GetGenericParameters().Select(h => reader.GetString(reader.GetGenericParameter(h).Name)).ToImmutableArray(); var genericTypeContext = new DisassemblingGenericContext(genericTypeParameters, ImmutableArray <string> .Empty); foreach (var fieldHandle in type.GetFields()) { FieldDefinition field = reader.GetFieldDefinition(fieldHandle); string fieldName = reader.GetString(field.Name); string expected; Assert.True(expectedFields.TryGetValue(fieldName, out expected), "Unexpected field: " + fieldName); Assert.Equal(expected, field.DecodeSignature(provider, genericTypeContext)); } Dictionary <string, string> expectedMethods = GetExpectedMethodSignatures(); foreach (var methodHandle in type.GetMethods()) { MethodDefinition method = reader.GetMethodDefinition(methodHandle); ImmutableArray <string> genericMethodParameters = method.GetGenericParameters().Select(h => reader.GetString(reader.GetGenericParameter(h).Name)).ToImmutableArray(); var genericMethodContext = new DisassemblingGenericContext(genericTypeParameters, genericMethodParameters); string methodName = reader.GetString(method.Name); string expected; Assert.True(expectedMethods.TryGetValue(methodName, out expected), "Unexpected method: " + methodName); MethodSignature <string> signature = method.DecodeSignature(provider, genericMethodContext); Assert.True(signature.Header.Kind == SignatureKind.Method); if (methodName.StartsWith("Generic")) { Assert.Equal(1, signature.GenericParameterCount); } else { Assert.Equal(0, signature.GenericParameterCount); } Assert.True(signature.GenericParameterCount <= 1 && (methodName != "GenericMethodParameter" || signature.GenericParameterCount == 1)); Assert.Equal(expected, provider.GetFunctionPointerType(signature)); } Dictionary <string, string> expectedProperties = GetExpectedPropertySignatures(); foreach (var propertyHandle in type.GetProperties()) { PropertyDefinition property = reader.GetPropertyDefinition(propertyHandle); string propertyName = reader.GetString(property.Name); string expected; Assert.True(expectedProperties.TryGetValue(propertyName, out expected), "Unexpected property: " + propertyName); MethodSignature <string> signature = property.DecodeSignature(provider, genericTypeContext); Assert.True(signature.Header.Kind == SignatureKind.Property); Assert.Equal(expected, provider.GetFunctionPointerType(signature)); } Dictionary <string, string> expectedEvents = GetExpectedEventSignatures(); foreach (var eventHandle in type.GetEvents()) { EventDefinition @event = reader.GetEventDefinition(eventHandle); string eventName = reader.GetString(@event.Name); string expected; Assert.True(expectedEvents.TryGetValue(eventName, out expected), "Unexpected event: " + eventName); Assert.Equal(expected, provider.GetTypeFromHandle(reader, genericTypeContext, @event.Type)); } Assert.Equal($"[{CollectionsAssemblyName}]System.Collections.Generic.List`1<!T>", provider.GetTypeFromHandle(reader, genericTypeContext, handle: type.BaseType)); } }
//private static void GetMethodFields(string name, IPersistentMap overloads, Dictionary<string, FieldBuilder> varMap, out FieldBuilder overloadFB, out FieldBuilder regularFB) //{ // if ( overloads.containsKey(name) ) //} static List<MethodSignature> GetAllSignatures(Type superClass, List<Type> interfaces, ISeq methods) { HashSet<MethodSignature> considered = new HashSet<MethodSignature>(); List<MethodSignature> todo = new List<MethodSignature>(); GetAllMethods(superClass,considered,todo,"super"); foreach( Type t in interfaces) GetAllMethods(t,considered,todo,"interface"); for (ISeq s = methods; s != null; s = s.next()) { IPersistentVector v = (IPersistentVector)s.first(); // v == [name [paramTypes...] returnType] string name = ((Symbol)v.nth(0)).Name; Type[] paramTypes = CreateTypeArray((ISeq)v.nth(1)); Type returnType = (Type)v.nth(2); bool isStatic = RT.booleanCast(v.nth(3)); MethodSignature sig = new MethodSignature(name, paramTypes, returnType, isStatic, "other"); if ( ! considered.Contains(sig) ) todo.Add(sig); considered.Add(sig); } return todo; }
//Single Entry point for CarFast //TODO: support other parameter types private void generateSingleEntry() { program += "\npublic static void singleEntry("; StringBuilder param = new StringBuilder(); for (int i = 0; i < ProgGenUtil.maxNoOfParameters; i++) { param.Append("int i" + i + ","); } string st = param.ToString(); st = st.Substring(0, st.Length - 1); st += "){\n"; program += st; program += this.fileName + " obj = new " + this.fileName + "();\n"; foreach (Method method in this.methodList) { HashSet <int?> set = new HashSet <int?>(); StringBuilder builder = new StringBuilder(); MethodSignature signature = method.MethodSignature; if (!signature.Static) { builder.Append("obj."); } builder.Append(signature.Name + "("); foreach (Variable variable in signature.ParameterList) { Type type = variable.Type; if (type.getType() == Type.Primitives.OBJECT) { builder.Append("new " + type.ToString() + "()"); builder.Append(","); } else { if (variable.Name.Equals("recursionCounter")) { builder.Append((new Random()).Next(ProgGenUtil.maxRecursionDepth)); } else { if (type.getType() != Type.Primitives.INT) { builder.Append(new Literal(type.getType())); } else { bool addedToSet = false; do { int @var = (new Random()).Next(ProgGenUtil.maxNoOfParameters); addedToSet = set.Add(@var); if (addedToSet) { builder.Append("i" + @var); } }while (!addedToSet); } } builder.Append(","); } } string str = builder.ToString(); str = str.Substring(0, str.Length - 1); str += ");\n"; program += str; } program += "}\n"; }
public void __SetCallingConvention(CallingConventions callingConvention) { this.callingConvention = callingConvention; this.methodSignature = null; }
public DynamicInvokeMethodSignature(MethodSignature concreteSignature) { Debug.Assert(DynamicInvokeMethodThunk.SupportsSignature(concreteSignature)); _signature = concreteSignature; }
// We'll never get function pointer types in any types we care about, so we can // just return the empty string. Similarly, as we never construct generics, // there is no need to provide anything for the generic parameter names. public EntityHandle GetFunctionPointerType(MethodSignature <EntityHandle> signature) => default;
public override MethodIL EmitIL() { ILEmitter emitter = new ILEmitter(); ILCodeStream argSetupStream = emitter.NewCodeStream(); ILCodeStream thisCallSiteSetupStream = emitter.NewCodeStream(); ILCodeStream staticCallSiteSetupStream = emitter.NewCodeStream(); ILCodeStream returnCodeStream = emitter.NewCodeStream(); // This function will look like // // !For each parameter to the method // !if (parameter is In Parameter) // localX is TypeOfParameterX& // ldarg.2 // ldtoken TypeOfParameterX // call DynamicInvokeParamHelperIn(ref ArgSetupState, RuntimeTypeHandle) // stloc localX // !else // localX is TypeOfParameter // ldarg.2 // ldtoken TypeOfParameterX // call DynamicInvokeParamHelperRef(ref ArgSetupState, RuntimeTypeHandle) // stloc localX // ldarg.2 // call DynamicInvokeArgSetupComplete(ref ArgSetupState) // *** Thiscall instruction stream starts here *** // ldarg.3 // Load targetIsThisCall // brfalse Not_this_call // ldarg.0 // Load this pointer // !For each parameter // !if (parameter is In Parameter) // ldloc localX // ldobj TypeOfParameterX // !else // ldloc localX // ldarg.1 // calli ReturnType thiscall(TypeOfParameter1, ...) // br Process_return // *** Static call instruction stream starts here *** // Not_this_call: // !For each parameter // !if (parameter is In Parameter) // ldloc localX // ldobj TypeOfParameterX // !else // ldloc localX // ldarg.1 // calli ReturnType (TypeOfParameter1, ...) // *** Return code stream starts here *** // Process_return: // !if (ReturnType is Byref) // dup // brfalse ByRefNull // ldobj ReturnType // !if ((ReturnType == void) // ldnull // !elif (ReturnType is pointer) // System.Reflection.Pointer.Box(ReturnType) // !else // box ReturnType // ret // // !if (ReturnType is ByRef) // ByRefNull: // throw NullReferenceException ILCodeLabel lStaticCall = emitter.NewCodeLabel(); ILCodeLabel lProcessReturn = emitter.NewCodeLabel(); thisCallSiteSetupStream.EmitLdArg(3); // targetIsThisCall thisCallSiteSetupStream.Emit(ILOpcode.brfalse, lStaticCall); staticCallSiteSetupStream.EmitLabel(lStaticCall); thisCallSiteSetupStream.EmitLdArg(0); // thisPtr ILToken tokDynamicInvokeParamHelperRef = emitter.NewToken(InvokeUtilsType.GetKnownMethod("DynamicInvokeParamHelperRef", null)); ILToken tokDynamicInvokeParamHelperIn = emitter.NewToken(InvokeUtilsType.GetKnownMethod("DynamicInvokeParamHelperIn", null)); TypeDesc[] targetMethodSignature = new TypeDesc[_targetSignature.Length]; for (int paramIndex = 0; paramIndex < _targetSignature.Length; paramIndex++) { TypeDesc paramType = Context.GetSignatureVariable(paramIndex, true); DynamicInvokeMethodParameterKind paramKind = _targetSignature[paramIndex]; for (int i = 0; i < _targetSignature.GetNumberOfParameterPointerIndirections(paramIndex); i++) { paramType = paramType.MakePointerType(); } ILToken tokParamType = emitter.NewToken(paramType); ILLocalVariable local = emitter.NewLocal(paramType.MakeByRefType()); thisCallSiteSetupStream.EmitLdLoc(local); staticCallSiteSetupStream.EmitLdLoc(local); argSetupStream.EmitLdArg(2); // argSetupState argSetupStream.Emit(ILOpcode.ldtoken, tokParamType); if (paramKind == DynamicInvokeMethodParameterKind.Reference) { argSetupStream.Emit(ILOpcode.call, tokDynamicInvokeParamHelperRef); targetMethodSignature[paramIndex] = paramType.MakeByRefType(); } else { argSetupStream.Emit(ILOpcode.call, tokDynamicInvokeParamHelperIn); thisCallSiteSetupStream.EmitLdInd(paramType); staticCallSiteSetupStream.EmitLdInd(paramType); targetMethodSignature[paramIndex] = paramType; } argSetupStream.EmitStLoc(local); } argSetupStream.EmitLdArg(2); // argSetupState argSetupStream.Emit(ILOpcode.call, emitter.NewToken(InvokeUtilsType.GetKnownMethod("DynamicInvokeArgSetupComplete", null))); thisCallSiteSetupStream.EmitLdArg(1); // methodToCall staticCallSiteSetupStream.EmitLdArg(1); // methodToCall DynamicInvokeMethodParameterKind returnKind = _targetSignature.ReturnType; TypeDesc returnType = returnKind != DynamicInvokeMethodParameterKind.None ? Context.GetSignatureVariable(_targetSignature.Length, true) : Context.GetWellKnownType(WellKnownType.Void); for (int i = 0; i < _targetSignature.GetNumerOfReturnTypePointerIndirections(); i++) { returnType = returnType.MakePointerType(); } if (returnKind == DynamicInvokeMethodParameterKind.Reference) { returnType = returnType.MakeByRefType(); } MethodSignature thisCallMethodSig = new MethodSignature(0, 0, returnType, targetMethodSignature); thisCallSiteSetupStream.Emit(ILOpcode.calli, emitter.NewToken(thisCallMethodSig)); thisCallSiteSetupStream.Emit(ILOpcode.br, lProcessReturn); MethodSignature staticCallMethodSig = new MethodSignature(MethodSignatureFlags.Static, 0, returnType, targetMethodSignature); staticCallSiteSetupStream.Emit(ILOpcode.calli, emitter.NewToken(staticCallMethodSig)); returnCodeStream.EmitLabel(lProcessReturn); ILCodeLabel lByRefReturnNull = null; if (returnKind == DynamicInvokeMethodParameterKind.None) { returnCodeStream.Emit(ILOpcode.ldnull); } else { TypeDesc returnTypeForBoxing = returnType; if (returnType.IsByRef) { // If this is a byref return, we need to dereference first returnTypeForBoxing = ((ByRefType)returnType).ParameterType; lByRefReturnNull = emitter.NewCodeLabel(); returnCodeStream.Emit(ILOpcode.dup); returnCodeStream.Emit(ILOpcode.brfalse, lByRefReturnNull); returnCodeStream.EmitLdInd(returnTypeForBoxing); } if (returnTypeForBoxing.IsPointer) { // Pointers box differently returnCodeStream.Emit(ILOpcode.ldtoken, emitter.NewToken(returnTypeForBoxing)); MethodDesc getTypeFromHandleMethod = Context.SystemModule.GetKnownType("System", "Type").GetKnownMethod("GetTypeFromHandle", null); returnCodeStream.Emit(ILOpcode.call, emitter.NewToken(getTypeFromHandleMethod)); MethodDesc pointerBoxMethod = Context.SystemModule.GetKnownType("System.Reflection", "Pointer").GetKnownMethod("Box", null); returnCodeStream.Emit(ILOpcode.call, emitter.NewToken(pointerBoxMethod)); } else { ILToken tokReturnType = emitter.NewToken(returnTypeForBoxing); returnCodeStream.Emit(ILOpcode.box, tokReturnType); } } returnCodeStream.Emit(ILOpcode.ret); if (lByRefReturnNull != null) { returnCodeStream.EmitLabel(lByRefReturnNull); MethodDesc nullReferencedExceptionHelper = Context.GetHelperEntryPoint("ThrowHelpers", "ThrowInvokeNullRefReturned"); returnCodeStream.EmitCallThrowHelper(emitter, nullReferencedExceptionHelper); } return(emitter.Link(this)); }
/// <summary> /// Checks if at least one Method satisfies a given MethodSignature. /// </summary> /// <param name="self">The TypeReference on which the extension method can be called.</param> /// <param name="signature">The MethodSignature to match.</param> /// <returns>True if at least one method matches the signature. Otherwise false.</returns> public static bool HasMethod(this TypeReference self, MethodSignature signature) { return((self != null) && self.GetMethod(signature) != null); }
public MutableMethodInfo CreateMethod( MutableType declaringType, string name, MethodAttributes attributes, IEnumerable <GenericParameterDeclaration> genericParameters, Func <GenericParameterContext, Type> returnTypeProvider, Func <GenericParameterContext, IEnumerable <ParameterDeclaration> > parameterProvider, Func <MethodBodyCreationContext, Expression> bodyProvider) { ArgumentUtility.CheckNotNull("declaringType", declaringType); ArgumentUtility.CheckNotNullOrEmpty("name", name); ArgumentUtility.CheckNotNull("genericParameters", genericParameters); ArgumentUtility.CheckNotNull("returnTypeProvider", returnTypeProvider); ArgumentUtility.CheckNotNull("parameterProvider", parameterProvider); // Body provider may be null (for abstract methods). // TODO 5478: virtual and static is an invalid combination var isAbstract = attributes.IsSet(MethodAttributes.Abstract); if (!isAbstract && bodyProvider == null) { throw new ArgumentNullException("bodyProvider", "Non-abstract methods must have a body."); } if (isAbstract && bodyProvider != null) { throw new ArgumentException("Abstract methods cannot have a body.", "bodyProvider"); } MemberAttributesUtility.ValidateAttributes("methods", MemberAttributesUtility.InvalidMethodAttributes, attributes, "attributes"); var isVirtual = attributes.IsSet(MethodAttributes.Virtual); var isNewSlot = attributes.IsSet(MethodAttributes.NewSlot); if (isAbstract && !isVirtual) { throw new ArgumentException("Abstract methods must also be virtual.", "attributes"); } if (!isVirtual && isNewSlot) { throw new ArgumentException("NewSlot methods must also be virtual.", "attributes"); } var methodItems = GetMethodSignatureItems(declaringType, genericParameters, returnTypeProvider, parameterProvider); var signature = new MethodSignature( methodItems.ReturnType, methodItems.ParameterDeclarations.Select(pd => pd.Type), methodItems.GenericParameters.Count, s_methodSignatureStringBuilderHelper); if (declaringType.AddedMethods.Any(m => m.Name == name && MethodSignature.Create(m).Equals(signature))) { throw new InvalidOperationException("Method with equal name and signature already exists."); } var baseMethod = GetBaseMethod(declaringType, name, signature, isVirtual, isNewSlot); // TODO 5478: if it is an implicit overriddenMethod override, it needs at least the same ore more public visibility var body = GetMethodBody(declaringType, attributes, bodyProvider, methodItems, baseMethod); return(new MutableMethodInfo( declaringType, name, attributes, methodItems.GenericParameters, methodItems.ReturnType, methodItems.ParameterDeclarations, baseMethod, body)); }