Browse Source

Revert "Extended the auto-compilation to add module initialisers, if any."

This reverts commit ec241510f7.
pull/736/head 0.8.2
Dimitar Dobrev 8 years ago
parent
commit
4e3cc50073
  1. 67
      deps/InjectModuleInitializer/Errors.cs
  2. 192
      deps/InjectModuleInitializer/Injector.cs
  3. BIN
      deps/Mono.Cecil/Mono.Cecil.Pdb.dll
  4. BIN
      deps/Mono.Cecil/Mono.Cecil.dll
  5. 21
      src/Generator/Driver.cs
  6. 2
      src/Generator/Utils/Utils.cs
  7. 11
      src/Generator/premake5.lua

67
deps/InjectModuleInitializer/Errors.cs vendored

@ -1,67 +0,0 @@ @@ -1,67 +0,0 @@
/*
InjectModuleInitializer
Command line program to inject a module initializer into a .NET assembly.
Copyright (C) 2009-2016 Einar Egilsson
http://einaregilsson.com/module-initializers-in-csharp/
This program is licensed under the MIT license: http://opensource.org/licenses/MIT
*/
using System;
namespace EinarEgilsson.Utilities.InjectModuleInitializer
{
internal static class Errors
{
internal static string AssemblyDoesNotExist(string assembly)
{
return String.Format("Assembly '{0}' does not exist", assembly);
}
internal static string NoModuleInitializerTypeFound()
{
return "Found no type named 'ModuleInitializer', this type must exist or the ModuleInitializer parameter must be used";
}
internal static string InvalidFormatForModuleInitializer()
{
return "Invalid format for ModuleInitializer parameter, use Full.Type.Name::MethodName";
}
internal static string TypeNameDoesNotExist(string typeName)
{
return string.Format("No type named '{0}' exists in the given assembly!", typeName);
}
internal static string MethodNameDoesNotExist(string typeName, string methodName)
{
return string.Format("No method named '{0}' exists in the type '{0}'", methodName, typeName);
}
internal static string KeyFileDoesNotExist(string keyfile)
{
return string.Format("The key file'{0}' does not exist", keyfile);
}
internal static string ModuleInitializerMayNotBePrivate()
{
return "Module initializer method may not be private or protected, use public or internal instead";
}
internal static string ModuleInitializerMustBeVoid()
{
return "Module initializer method must have 'void' as return type";
}
internal static string ModuleInitializerMayNotHaveParameters()
{
return "Module initializer method must not have any parameters";
}
internal static string ModuleInitializerMustBeStatic()
{
return "Module initializer method must be static";
}
}
}

192
deps/InjectModuleInitializer/Injector.cs vendored

@ -1,192 +0,0 @@ @@ -1,192 +0,0 @@
/*
InjectModuleInitializer
Command line program to inject a module initializer into a .NET assembly.
Copyright (C) 2009-2016 Einar Egilsson
http://einaregilsson.com/module-initializers-in-csharp/
This program is licensed under the MIT license: http://opensource.org/licenses/MIT
*/
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Pdb;
using Mono.Collections.Generic;
using MethodAttributes = Mono.Cecil.MethodAttributes;
namespace EinarEgilsson.Utilities.InjectModuleInitializer
{
public class InjectionException : Exception
{
public InjectionException(string msg) : base(msg) { }
}
internal class Injector
{
public const string DefaultInitializerClassName = "ModuleInitializer";
public const string DefaultInitializerMethodName = "Run";
private AssemblyDefinition Assembly { get; set; }
private string PdbFile(string assemblyFile)
{
Debug.Assert(assemblyFile != null);
string path = Path.ChangeExtension(assemblyFile, ".pdb");
if (File.Exists(path))
{
return path;
}
return null;
}
public void Inject(string assemblyFile, string moduleInitializer=null, string keyfile=null)
{
try
{
if (!File.Exists(assemblyFile))
{
throw new InjectionException(Errors.AssemblyDoesNotExist(assemblyFile));
}
if (keyfile != null && !File.Exists(keyfile))
{
throw new InjectionException(Errors.KeyFileDoesNotExist(keyfile));
}
ReadAssembly(assemblyFile);
MethodReference callee = GetModuleInitializer(moduleInitializer);
InjectInitializer(callee);
WriteAssembly(assemblyFile, keyfile);
}
catch (Exception ex)
{
throw new InjectionException(ex.Message);
}
}
public void InjectInitializer(MethodReference callee)
{
Debug.Assert(Assembly != null);
TypeReference voidRef = Assembly.MainModule.Import(callee.ReturnType);
const MethodAttributes attributes = MethodAttributes.Static
| MethodAttributes.SpecialName
| MethodAttributes.RTSpecialName;
var cctor = new MethodDefinition(".cctor", attributes, voidRef);
ILProcessor il = cctor.Body.GetILProcessor();
il.Append(il.Create(OpCodes.Call, callee));
il.Append(il.Create(OpCodes.Ret));
TypeDefinition moduleClass = Find(Assembly.MainModule.Types, t => t.Name == "<Module>");
moduleClass.Methods.Add(cctor);
Debug.Assert(moduleClass != null, "Found no module class!");
}
public void WriteAssembly(string assemblyFile, string keyfile)
{
Debug.Assert(Assembly != null);
var writeParams = new WriterParameters();
if (PdbFile(assemblyFile) != null)
{
writeParams.WriteSymbols = true;
writeParams.SymbolWriterProvider = new PdbWriterProvider();
}
if (keyfile != null)
{
writeParams.StrongNameKeyPair = new StrongNameKeyPair(File.ReadAllBytes(keyfile));
}
Assembly.Write(assemblyFile, writeParams);
}
public void ReadAssembly(string assemblyFile)
{
Debug.Assert(Assembly == null);
var resolver = new DefaultAssemblyResolver();
resolver.AddSearchDirectory(Path.GetDirectoryName(assemblyFile));
var readParams = new ReaderParameters(ReadingMode.Immediate)
{
AssemblyResolver = resolver
};
if (PdbFile(assemblyFile) != null)
{
readParams.ReadSymbols = true;
readParams.SymbolReaderProvider = new PdbReaderProvider();
}
Assembly = AssemblyDefinition.ReadAssembly(assemblyFile, readParams);
}
public MethodReference GetModuleInitializer(string moduleInitializer = null)
{
Debug.Assert(Assembly != null);
ModuleDefinition module = Assembly.MainModule;
string methodName;
TypeDefinition moduleInitializerClass;
if (string.IsNullOrEmpty(moduleInitializer))
{
methodName = DefaultInitializerMethodName;
moduleInitializerClass = Find(module.Types, t => t.Name == DefaultInitializerClassName);
if (moduleInitializerClass == null)
{
return null;
}
}
else
{
if (!moduleInitializer.Contains("::"))
{
return null;
}
string typeName = moduleInitializer.Substring(0, moduleInitializer.IndexOf("::", StringComparison.Ordinal));
methodName = moduleInitializer.Substring(typeName.Length + 2);
moduleInitializerClass = Find(module.Types, t => t.FullName == typeName);
if (moduleInitializerClass == null)
{
return null;
}
}
MethodDefinition callee = Find(moduleInitializerClass.Methods, m => m.Name == methodName);
if (callee == null)
{
throw new InjectionException(Errors.MethodNameDoesNotExist(moduleInitializerClass.FullName, methodName));
}
if (callee.Parameters.Count > 0)
{
throw new InjectionException(Errors.ModuleInitializerMayNotHaveParameters());
}
if (callee.IsPrivate || callee.IsFamily)
{
throw new InjectionException(Errors.ModuleInitializerMayNotBePrivate());
}
if (!callee.ReturnType.FullName.Equals(typeof(void).FullName)) //Don't compare the types themselves, they might be from different CLR versions.
{
throw new InjectionException(Errors.ModuleInitializerMustBeVoid());
}
if (!callee.IsStatic)
{
throw new InjectionException(Errors.ModuleInitializerMustBeStatic());
}
return callee;
}
//No LINQ, since we want to target 2.0
private static T Find<T>(Collection<T> objects, Predicate<T> condition) where T:class
{
foreach (T obj in objects)
{
if (condition(obj))
{
return obj;
}
}
return null;
}
}
}

BIN
deps/Mono.Cecil/Mono.Cecil.Pdb.dll vendored

Binary file not shown.

BIN
deps/Mono.Cecil/Mono.Cecil.dll vendored

Binary file not shown.

21
src/Generator/Driver.cs

@ -15,7 +15,6 @@ using CppSharp.Passes; @@ -15,7 +15,6 @@ using CppSharp.Passes;
using CppSharp.Types;
using CppSharp.Parser;
using CppSharp.Utils;
using EinarEgilsson.Utilities.InjectModuleInitializer;
namespace CppSharp
{
@ -449,7 +448,6 @@ namespace CppSharp @@ -449,7 +448,6 @@ namespace CppSharp
HasCompilationErrors = errors.Count > 0;
if (!HasCompilationErrors)
{
InjectModuleInitializer(assemblyFile);
Diagnostics.Message("Compilation succeeded.");
var wrapper = Path.Combine(outputDir, assemblyFile);
foreach (var library in module.Libraries)
@ -457,25 +455,6 @@ namespace CppSharp @@ -457,25 +455,6 @@ namespace CppSharp
}
}
/// <summary>
/// Injects a module initializer, if any, i.e. code executed right after an
/// assembly is loaded and before any other code in it.
/// <para>The run-time supports it but C# does not so we inject it in the
/// compiled assembly by manually adding IL instructions.</para>
/// </summary>
/// <param name="assemblyFile">The assembly to inject a module initializer to.</param>
private static void InjectModuleInitializer(string assemblyFile)
{
var injector = new Injector();
injector.ReadAssembly(assemblyFile);
var moduleInitializer = injector.GetModuleInitializer();
if (moduleInitializer != null)
{
injector.InjectInitializer(moduleInitializer);
injector.WriteAssembly(assemblyFile, null);
}
}
public void AddTranslationUnitPass(TranslationUnitPass pass)
{
Context.TranslationUnitPasses.AddPass(pass);

2
src/Generator/Utils/Utils.cs

@ -132,7 +132,7 @@ namespace CppSharp @@ -132,7 +132,7 @@ namespace CppSharp
public static IEnumerable<Type> FindDerivedTypes(this Assembly assembly,
Type baseType)
{
return assembly.GetExportedTypes().Where(baseType.IsAssignableFrom);
return assembly.GetTypes().Where(baseType.IsAssignableFrom);
}
}

11
src/Generator/premake5.lua

@ -5,23 +5,16 @@ project "CppSharp.Generator" @@ -5,23 +5,16 @@ project "CppSharp.Generator"
kind "SharedLib"
language "C#"
files { "**.cs", "**verbs.txt", path.join(depsdir, "InjectModuleInitializer", "**.cs") }
files { "**.cs", "**verbs.txt" }
excludes { "Filter.cs" }
libdirs
{
depsdir .. "/Mono.Cecil"
}
links
{
"System",
"System.Core",
"CppSharp",
"CppSharp.AST",
"CppSharp.Parser",
"Mono.Cecil",
"Mono.Cecil.Pdb"
"CppSharp.Parser"
}
SetupParser()

Loading…
Cancel
Save