Я в настоящее время погружаюсь во внутренние работы .NET, что означает IL. Как осуществление, я хочу создать brainf.. k компилятор для .NET (да, они уже существуют, но, как сказано это для изучения целей).
В настоящий момент я просто пишу некоторые текстовые файлы, которые содержат .il и компилируют их с ilasm, который работает. Но интересно, мог ли я пойти один уровень глубже и записать байт-код непосредственно?
Мое "беспокойство" является Windows PE Stuff при компиляции EXE - вместо ilasm, мне был бы нужен своего рода компоновщик Байт-кода, который возьмет мой байт-код MSIL/CIL и генерирует Материал PE для него?
Или компиляторы "только" компилируют свой язык в IL и выполняют ilasm? Существует ли управляемая версия его, что я могу назвать/встроить из своего компилятора?
Почему бы просто не использовать API Reflection.Emit для создания сборки в памяти с скомпилированным кодом, а затем сохранить ее на диск? Должно быть намного проще, чем записывать файлы .IL.
Ссылки:
Если вы хотите пойти по этому пути, задайте более конкретные вопросы здесь, на SO , вы получите множество примеров того, как определить динамическую сборку и сохранить ее на диск.
Вот пример:
using System;
using System.Reflection.Emit;
using System.Reflection;
namespace SO2598958
{
class Program
{
static void Main()
{
AssemblyBuilder asm = AppDomain.CurrentDomain.DefineDynamicAssembly(
new AssemblyName("TestOutput"),
AssemblyBuilderAccess.RunAndSave);
ModuleBuilder mod = asm.DefineDynamicModule("TestOutput.exe",
"TestOutput.exe");
TypeBuilder type = mod.DefineType("Program", TypeAttributes.Class);
MethodBuilder main = type.DefineMethod("Main",
MethodAttributes.Public | MethodAttributes.Static);
ILGenerator il = main.GetILGenerator();
il.Emit(OpCodes.Ldstr, "Hello world!");
il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine",
BindingFlags.Public | BindingFlags.Static,
null, new Type[] { typeof(String) }, null));
il.Emit(OpCodes.Ret);
type.CreateType();
asm.SetEntryPoint(main);
asm.Save("TestOutput.exe");
}
}
}
Вы можете скачать файл тестового решения отсюда . Прямая ссылка на zip-файл с решением здесь .
Если вы сначала скомпилируете и запустите эту программу, она создаст на диске новый exe-файл под названием TestOutput, который вы затем сможете выполнить, чтобы получить «Hello World!». напечатано на консоли.
С новым DLR можно создавать код, используя классы .Net. Я не уверен, насколько он защищает вас от фактического IL / байт-кода, поскольку это то, что вы пытаетесь изучить.
Reflection.Emit будет более простым для ваших целей, но вы можете взглянуть на проект Common Compiler Infrastructure на CodePlex тоже.
Вот краткое изложение страницы этого проекта:
Инфраструктура Microsoft Research Common Compiler (CCI) - это набор библиотек и приложения для программирования интерфейс (API), который поддерживает некоторые функции , которые являются общими для компиляторов и связанных инструментов программирования.
CCI Metadata API позволяет приложениям эффективно анализировать или изменять сборки, модули и файлы отладки (PDB) .NET. Метаданные CCI поддерживают функциональные возможности API .NET System.Reflection и System.Reflection.Emit, но с гораздо более высокой производительностью. Он также предоставляет дополнительные функции, которые недоступны ни в одном из .NET API.
В этом проекте есть PeWriter / PeReader среди всего прочего, что вам понадобится для написания компилятора .net (ILGenerator, помощники по метаданным и т. Д.).
Если я правильно понял ваш вопрос, вы, по крайней мере, нарушите переносимость, напрямую реализовав джиттинг. Оставьте этот материал командам .NET, Mono или всем остальным. Так что я думаю, тебе не стоит. Но насчет части вашего вопроса "мог бы" - я думаю, вы можете пропустить IL и скомпилировать все, что захотите (насколько я знаю, MonoTouch, MonoDroid и т. Д. Делают это): Из Википедии
В отличие от приложений Mono, «Приложения» MonoTouch компилируются в машинный код, предназначенный специально для Apple iPhone.
System.Reflection.Emit
предоставляет средства для создания IL кода статически-типизированным способом без необходимости генерировать и компилировать текстовые файлы с IL.
Вы можете посмотреть здесь: http://msdn.microsoft.com/es-es/library/system.reflection.emit.aspx
вы можете посмотреть здесь очень простой компилятор .net: