/// <summary> /// Get a symbol representing a type in the assembly. /// </summary> /// <param name="unit">Module calling the type.</param> /// <param name="type">Name of the type.</param> /// <param name="assembly">Assembly containing the type.</param> /// <returns>Symbol representing the type.</returns> private static Phx.Symbols.MsilTypeSymbol GetTypeSymbol(Phx.ModuleUnit unit, string type, Phx.Symbols.AssemblySymbol assembly) { Phx.Symbols.MsilTypeSymbol typeSymbol = null; // Look for any existing symbol foreach (Phx.Symbols.Symbol symbol in unit.SymbolTable.AllSymbols) { Phx.Symbols.MsilTypeSymbol s = symbol as Phx.Symbols.MsilTypeSymbol; if (s != null && s.NameString.Equals(type)) { typeSymbol = s; break; } } if (typeSymbol == null) { // Create the symbol if not found Phx.Name classTypeName = Phx.Name.New(unit.Lifetime, type); typeSymbol = Phx.Symbols.MsilTypeSymbol.New(unit.SymbolTable, classTypeName, 0); // Add the type to the assembly's scope assembly.InsertInLexicalScope(typeSymbol, classTypeName); } return(typeSymbol); }
/// <summary> /// Get a symbol representing a function that takes an unsigned integer /// parameter. /// </summary> /// <param name="unit">Module calling the function.</param> /// <param name="assembly">Name of the assembly.</param> /// <param name="type">Name of the class.</param> /// <param name="method">Name of the function.</param> /// <returns>FunctionSymbol representing the function.</returns> private static Phx.Symbols.FunctionSymbol GetFunctionSymbol(Phx.PEModuleUnit unit, string assembly, string type, string method) { // Look the function up in the cache Phx.Symbols.FunctionSymbol functionSymbol = null; if (FunctionSymbols.TryGetValue(unit, out functionSymbol) && functionSymbol != null) { return(functionSymbol); } // Create symbols for the assemblies and types Phx.Symbols.AssemblySymbol assemblySymbol = GetAssemblySymbol(unit, assembly); Phx.Symbols.MsilTypeSymbol typeSymbol = GetTypeSymbol(unit, type, assemblySymbol); // Build a symbol reference Phx.Types.FunctionTypeBuilder builder = Phx.Types.FunctionTypeBuilder.New(unit.TypeTable); builder.Begin(); builder.CallingConventionKind = Phx.Types.CallingConventionKind.ClrCall; builder.AppendReturnParameter(unit.TypeTable.VoidType); builder.AppendParameter(unit.TypeTable.UInt32Type); // Create the function symbol Phx.Name name = Phx.Name.New(unit.Lifetime, method); functionSymbol = Phx.Symbols.FunctionSymbol.New(unit.SymbolTable, 0, name, builder.GetFunctionType(), Phx.Symbols.Visibility.GlobalReference); typeSymbol.InsertInLexicalScope(functionSymbol, name); // Create a type Phx.Types.AggregateType aggregate = Phx.Types.AggregateType.NewDynamicSize(unit.TypeTable, typeSymbol); aggregate.IsDefinition = false; aggregate.AppendMethodSymbol(functionSymbol); // Cache the function FunctionSymbols[unit] = functionSymbol; return(functionSymbol); }
/// <summary> /// Get a symbol representing the assembly. /// </summary> /// <param name="unit">Module calling the assembly.</param> /// <param name="assembly">Name of the assembly.</param> /// <returns>Symbol representing the assembly.</returns> private static Phx.Symbols.AssemblySymbol GetAssemblySymbol(Phx.ModuleUnit unit, string assembly) { Phx.Symbols.AssemblySymbol assemblySymbol = null; // Look for any existing symbol foreach (Phx.Symbols.Symbol symbol in unit.SymbolTable.AllSymbols) { Phx.Symbols.AssemblySymbol s = symbol as Phx.Symbols.AssemblySymbol; if (s != null && s.NameString.Equals(assembly)) { assemblySymbol = s; break; } } if (assemblySymbol == null) { // Create the assembly manifest Phx.Name name = Phx.Name.New(unit.Lifetime, assembly); Phx.Version version = Phx.Version.New(unit.Lifetime); // A bug in Phx.Version ToString renders this field incorrect in // the debugger, FYI. version.MajorVersion = (ushort)CoverageVisitAssemblyVersion.Major; version.MinorVersion = (ushort)CoverageVisitAssemblyVersion.Minor; version.BuildNumber = (ushort)CoverageVisitAssemblyVersion.Build; version.RevisionNumber = (ushort)CoverageVisitAssemblyVersion.Revision; Phx.Manifest manifest = Phx.Manifest.New(unit.Lifetime); manifest.Name = name; manifest.HashAlgorithm = 0x00008004; manifest.Version = version; if (!string.IsNullOrEmpty(CoverageVisitAssemblyPublicKey)) { byte[] key = PublicKeyTokenToBytes(CoverageVisitAssemblyPublicKey); if (key != null) { Phx.PublicKey pk = Phx.PublicKey.New(unit.Lifetime); pk.IsPublicKeyToken = true; pk.KeyLength = (uint)key.Length; pk.Key = key; manifest.PublicKey = pk; } } // Create the assembly symbol if not found assemblySymbol = Phx.Symbols.AssemblySymbol.New(null, manifest, name, unit.SymbolTable); } return(assemblySymbol); }