Написание компилятора для .net - IL или Bytecode?
В настоящее время я погружаюсь во внутренние работы .net, что означает IL. В качестве упражнения я хочу построить компилятор brainf..k для .net(да, они уже существуют, но, как сказано в целях обучения).
На данный момент я просто пишу текстовые файлы, содержащие .il, и компилирую их с помощью ilasm, который работает. Но мне интересно, могу ли я/мог идти на один уровень глубже и писать байткод напрямую?
Мое "беспокойство" - это материал Windows PE при компиляции EXE - вместо ilasm мне нужен какой-то компоновщик Bytecode, который возьмет мой байт-код MSIL/CIL и сгенерирует PE-материал для него?
Или компиляторы "только" компилируют свой язык в IL и выполняют ilasm? Есть ли управляемая версия, которую я могу вызвать/внедрить из моего компилятора?
Ответы
Ответ 1
Почему бы просто не использовать Reflection.Emit api для создания сборки в памяти с помощью скомпилированного кода, а затем сохранить его на диск? Должно быть намного проще, чем писать файлы .IL.
Ссылки:
Если вы хотите спуститься по этой дороге, если вы зададите более конкретные вопросы здесь, на /fooobar.com/..., вы получите много примеров того, как определить динамическую сборку и сохраните его на диск.
Вот пример:
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!". напечатан на консоли.
Ответ 2
System.Reflection.Emit
предоставляет средства для создания кода IL в статически типизированном виде без необходимости генерации и компиляции текстовых файлов с помощью IL.
Ответ 3
Reflection.Emit будет более понятным для ваших целей, но вы можете посмотреть проект Common Compiler Infrastructure на CodePlex тоже.
Вот сводка на странице проекта для этого проекта:
Общий компилятор Microsoft Research Инфраструктура (CCI) представляет собой набор библиотеки и приложение программный интерфейс (API), который поддерживает некоторые функции что является общим для компиляторов и связанных с программным обеспечением.
API метаданных CCI позволяет приложений для эффективного анализа или модифицировать сборки, модули и отладки (PDB). Метаданные CCI поддерживает функции .NET. System.Reflection и System.Reflection.Emit API, но с намного лучше. Это также обеспечивает дополнительную функциональность, которая не доступен ни в .NET API.
Этот проект имеет PeWriter/PeReader среди всех других вещей, которые вам нужно будет написать .net-компилятор (ILGenerator, помощники метаданных и т.д.).
Ответ 4
С помощью новой DLR нужно иметь возможность создавать код с использованием классов .Net. Я не уверен, насколько он защищает вас от фактического IL/байт-кода, так как это то, что вы пытаетесь изучить.
Ответ 5
Вы можете посмотреть там: http://msdn.microsoft.com/es-es/library/system.reflection.emit.aspx
Ответ 6
вы можете легко найти компилятор .net:
http://msdn.microsoft.com/en-us/magazine/cc136756.aspx
Ответ 7
Если бы я правильно понял ваш вопрос, вы, по крайней мере, будете нарушать переносимость, непосредственно внедряя jitting. Оставьте этот материал .NET, Mono, какими бы ни были команды. Поэтому я думаю, что не стоит. Но о "может" часть вашего вопроса - я думаю, вы можете пропустить IL и скомпилировать все, что захотите (насколько я знаю, MonoTouch, MonoDroid и т.д.):
Из Википедии
В отличие от приложений Mono MonoTouch "Приложения" скомпилированы до машинного кода, ориентированного именно на Apple iPhone.