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()); }
/// <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];
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); }
public SynthesizedDelegateKey(int parameterCount, RefKindVector byRefs, bool returnsVoid, int generation) { _parameterCount = (ushort)parameterCount; _returnsVoid = returnsVoid; _generation = generation; _byRefs = byRefs; }
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)); }