/// <summary> /// Declares a method. /// </summary> /// <param name="methodBase">The method to declare.</param> /// <param name="created">True, if the method has been created.</param> /// <returns>The declared method.</returns> public Method Declare(MethodBase methodBase, out bool created) { Debug.Assert(methodBase != null, "Invalid method base"); // Check for existing method irLock.EnterUpgradeableReadLock(); try { if (methods.TryGetHandle(methodBase, out MethodHandle handle)) { created = false; return(methods[handle]); } var externalAttribute = methodBase.GetCustomAttribute < ExternalAttribute>(); var methodName = externalAttribute?.Name ?? methodBase.Name; handle = MethodHandle.Create(methodName); var declaration = new MethodDeclaration( handle, CreateType(methodBase.GetReturnType()), methodBase); return(Declare(declaration, out created)); } finally { irLock.ExitUpgradeableReadLock(); } }
/// <summary> /// Constructs a new method declaration. /// </summary> /// <param name="handle">The method handle (may be an empty handle).</param> /// <param name="returnType">The return type.</param> /// <param name="source">The source method.</param> public MethodDeclaration( MethodHandle handle, TypeNode returnType, MethodBase source) : this(handle, returnType, source, MethodFlags.None) { }
/// <summary> /// Returns data that corresponds to the given handle. /// </summary> /// <param name="handle">The function handle.</param> /// <returns>The resolved data.</returns> public T this[MethodHandle handle] { get { if (handle.IsEmpty) { return(default);
/// <summary> /// Declares a method. /// </summary> /// <param name="methodBase">The method to declare.</param> /// <param name="created">True, if the method has been created.</param> /// <returns>The declared method.</returns> public Method Declare(MethodBase methodBase, out bool created) { Debug.Assert(methodBase != null, "Invalid method base"); // Synchronize all accesses below using a read scope using var readScope = irLock.EnterUpgradeableReadScope(); // Check for existing method if (methods.TryGetHandle(methodBase, out MethodHandle handle)) { created = false; return(methods[handle]); } var externalAttribute = methodBase.GetCustomAttribute <ExternalAttribute>(); var methodName = externalAttribute?.Name ?? methodBase.Name; handle = MethodHandle.Create(methodName); var declaration = new MethodDeclaration( handle, CreateType(methodBase.GetReturnType()), methodBase); // Declare a new method sync using a write scope using var writeScope = readScope.EnterWriteScope(); return(Declare_Sync(declaration, out created)); }
/// <summary> /// Constructs a new method declaration. /// </summary> /// <param name="handle">The method handle (may be an empty handle).</param> /// <param name="returnType">The return type.</param> /// <param name="flags">Custom method flags.</param> public MethodDeclaration( MethodHandle handle, TypeNode returnType, MethodFlags flags) : this(handle, returnType, null, flags) { }
/// <summary> /// Constructs a new method declaration with an implicit handle. /// </summary> /// <param name="name">The method name.</param> /// <param name="returnType">The return type.</param> /// <param name="flags">Custom method flags.</param> public MethodDeclaration( string name, TypeNode returnType, MethodFlags flags) : this(MethodHandle.Create(name), returnType, flags) { }
/// <summary> /// Resolves the given method to a top-level function. /// </summary> /// <param name="method">The method to resolve.</param> /// <returns>The resolved function.</returns> public Method GetMethod(MethodHandle method) { if (!TryGetMethod(method, out Method function)) { throw new InvalidOperationException(string.Format( ErrorMessages.CouldNotFindCorrespondingIRMethod, method.Name)); } return(function); }
/// <summary> /// Tries to resolve the given managed method to function reference. /// </summary> /// <param name="method">The method to resolve.</param> /// <param name="handle">The resolved function reference (if any).</param> /// <returns>True, if the requested function could be resolved.</returns> public bool TryGetMethodHandle(MethodBase method, out MethodHandle handle) { if (method == null) { throw new ArgumentNullException(nameof(method)); } // Synchronize all accesses below using a read scope using var readScope = irLock.EnterUpgradeableReadScope(); return(methods.TryGetHandle(method, out handle)); }
/// <summary> /// Tries to resolve the given handle to a top-level function. /// </summary> /// <param name="handle">The function handle to resolve.</param> /// <param name="function">The resolved function (if any).</param> /// <returns>True, if the requested function could be resolved.</returns> public bool TryGetMethod(MethodHandle handle, out Method function) { if (handle.IsEmpty) { function = null; return(false); } // Synchronize all accesses below using a read scope using var readScope = irLock.EnterUpgradeableReadScope(); return(methods.TryGetData(handle, out function)); }
/// <summary> /// Constructs a new method declaration. /// </summary> /// <param name="handle">The method handle (may be an empty handle).</param> /// <param name="returnType">The return type.</param> /// <param name="source">The source method.</param> /// <param name="flags">Custom method flags.</param> public MethodDeclaration( MethodHandle handle, TypeNode returnType, MethodBase source, MethodFlags flags) { Handle = handle; ReturnType = returnType ?? throw new ArgumentNullException(nameof(returnType)); Source = source; Flags = flags; if (flags == MethodFlags.None && Source != null) { Flags = Method.ResolveMethodFlags(source); } }
/// <summary> /// Tries to resolve the given managed method to function reference. /// </summary> /// <param name="method">The method to resolve.</param> /// <param name="handle">The resolved function reference (if any).</param> /// <returns>True, if the requested function could be resolved.</returns> public bool TryGetMethodHandle(MethodBase method, out MethodHandle handle) { if (method == null) { throw new ArgumentNullException(nameof(method)); } irLock.EnterReadLock(); try { return(methods.TryGetHandle(method, out handle)); } finally { irLock.ExitReadLock(); } }
/// <summary> /// Tries to resolve the given handle to a top-level function. /// </summary> /// <param name="handle">The function handle to resolve.</param> /// <param name="function">The resolved function (if any).</param> /// <returns>True, if the requested function could be resolved.</returns> public bool TryGetMethod(MethodHandle handle, out Method function) { if (handle.IsEmpty) { function = null; return(false); } irLock.EnterReadLock(); try { return(methods.TryGetData(handle, out function)); } finally { irLock.ExitReadLock(); } }
/// <summary> /// Tries to resolve the given handle to a top-level function. /// </summary> /// <param name="handle">The function handle to resolve.</param> /// <param name="data">The resolved data (if any).</param> /// <returns>True, if the requested function could be resolved.</returns> public bool TryGetFunction(MethodHandle handle, out T data) => Parent.TryGetData(handle, out data);
/// <summary> /// Tries to resolve the given managed method to function reference. /// </summary> /// <param name="method">The method to resolve.</param> /// <param name="handle">The resolved function handle (if any).</param> /// <returns>True, if the requested function could be resolved.</returns> public bool TryGetHandle(MethodBase method, out MethodHandle handle) => Parent.TryGetHandle(method, out handle);
/// <summary> /// Returns data that corresponds to the given handle. /// </summary> /// <param name="handle">The function handle.</param> /// <returns>The resolved data.</returns> public T this[MethodHandle handle] => Parent[handle];
/// <summary> /// Specializes the current method declaration by specializing /// an empty method handle. /// </summary> /// <param name="handle">The handle to specialize.</param> /// <returns>The specialized method declaration.</returns> public MethodDeclaration Specialize(MethodHandle handle) { Debug.Assert(!handle.IsEmpty, "Invalid handle"); return(new MethodDeclaration(handle, ReturnType, Source, Flags)); }