Esempio n. 1
0
        internal static string MakeDynamicCallSiteDelegateName(RefKindVector byRefs, bool returnsVoid, int generation)
        {
            var pooledBuilder = PooledStringBuilder.GetInstance();
            var builder       = pooledBuilder.Builder;

            builder.Append(returnsVoid ? "<>A" : "<>F");

            if (!byRefs.IsNull)
            {
                builder.Append("{");

                int i = 0;
                foreach (int byRefIndex in byRefs.Words())
                {
                    if (i > 0)
                    {
                        builder.Append(",");
                    }

                    builder.AppendFormat("{0:x8}", byRefIndex);
                    i++;
                }

                builder.Append("}");
                Debug.Assert(i > 0);
            }

            AppendOptionalGeneration(builder, generation);
            return(pooledBuilder.ToStringAndFree());
        }
Esempio n. 2
0
        /// <summary>
        /// Parses the name of a synthesized delegate out into the things it represents.
        /// </summary>
        /// <remarks>
        /// Logic here should match <see cref="MakeSynthesizedDelegateName" />.
        /// </remarks>
        internal static bool TryParseSynthesizedDelegateName(string name, out RefKindVector byRefs, out bool returnsVoid, out int generation, out int parameterCount)
        {
            byRefs         = default;
            parameterCount = 0;
            generation     = 0;

            name = MetadataHelpers.InferTypeArityAndUnmangleMetadataName(name, out var arity);

            returnsVoid = name.StartsWith(ActionDelegateNamePrefix);

            if (!returnsVoid && !name.StartsWith(FuncDelegateNamePrefix))
            {
                return(false);
            }

            parameterCount = arity - (returnsVoid ? 0 : 1);

            // If there are no ref kinds encoded
            // (and therefore no braces), use the end of the prefix instead.
            var nameEndIndex = name.LastIndexOf('}');

            if (nameEndIndex < 0)
            {
                nameEndIndex = DelegateNamePrefixLength - 1;
            }
            else
            {
                // There should be a character after the prefix, and it should be an open brace
                if (name.Length <= DelegateNamePrefixLength || name[DelegateNamePrefixLength] != '{')
                {
                    return(false);
                }

                // If there are braces, then the ref kind string is encoded between them
                var refKindString = name[DelegateNamePrefixLengthWithOpenBrace..nameEndIndex];
Esempio n. 3
0
        internal SynthesizedDelegateSymbol SynthesizeDelegate(int parameterCount, RefKindVector refKinds, bool returnsVoid, int generation)
        {
            // parameterCount doesn't include return type
            Debug.Assert(refKinds.IsNull || parameterCount == refKinds.Capacity - (returnsVoid ? 0 : 1));

            var key = new SynthesizedDelegateKey(parameterCount, refKinds, returnsVoid, generation);

            SynthesizedDelegateValue result;

            if (this.SynthesizedDelegates.TryGetValue(key, out result))
            {
                return(result.Delegate);
            }

            // NOTE: the newly created template may be thrown away if another thread wins
            var synthesizedDelegate = new SynthesizedDelegateSymbol(
                this.Compilation.Assembly.GlobalNamespace,
                key.MakeTypeName(),
                this.System_Object,
                Compilation.GetSpecialType(SpecialType.System_IntPtr),
                returnsVoid ? Compilation.GetSpecialType(SpecialType.System_Void) : null,
                parameterCount,
                refKinds);

            return(this.SynthesizedDelegates.GetOrAdd(key, new SynthesizedDelegateValue(this, synthesizedDelegate)).Delegate);
        }
Esempio n. 4
0
 public SynthesizedDelegateKey(int parameterCount, RefKindVector byRefs, bool returnsVoid, int generation)
 {
     _parameterCount = (ushort)parameterCount;
     _returnsVoid    = returnsVoid;
     _generation     = generation;
     _byRefs         = byRefs;
 }
Esempio n. 5
0
        private SynthesizedDelegateValue CreatePlaceholderSynthesizedDelegateValue(string name, RefKindVector refKinds, bool returnsVoid, int parameterCount)
        {
            var symbol = new SynthesizedDelegateSymbol(
                this.Compilation.Assembly.GlobalNamespace,
                MetadataHelpers.InferTypeArityAndUnmangleMetadataName(name, out _),
                this.System_Object,
                Compilation.GetSpecialType(SpecialType.System_IntPtr),
                returnsVoid ? Compilation.GetSpecialType(SpecialType.System_Void) : null,
                parameterCount,
                refKinds);

            return(new SynthesizedDelegateValue(this, symbol));
        }