Запись компилятора для .NET - IL или байт-код?

Я в настоящее время погружаюсь во внутренние работы .NET, что означает IL. Как осуществление, я хочу создать brainf.. k компилятор для .NET (да, они уже существуют, но, как сказано это для изучения целей).

В настоящий момент я просто пишу некоторые текстовые файлы, которые содержат .il и компилируют их с ilasm, который работает. Но интересно, мог ли я пойти один уровень глубже и записать байт-код непосредственно?

Мое "беспокойство" является Windows PE Stuff при компиляции EXE - вместо ilasm, мне был бы нужен своего рода компоновщик Байт-кода, который возьмет мой байт-код MSIL/CIL и генерирует Материал PE для него?

Или компиляторы "только" компилируют свой язык в IL и выполняют ilasm? Существует ли управляемая версия его, что я могу назвать/встроить из своего компилятора?

27
задан Michael Stum 8 April 2010 в 10:05
поделиться

7 ответов

Почему бы просто не использовать 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!». напечатано на консоли.

27
ответ дан 28 November 2019 в 05:43
поделиться

С новым DLR можно создавать код, используя классы .Net. Я не уверен, насколько он защищает вас от фактического IL / байт-кода, поскольку это то, что вы пытаетесь изучить.

0
ответ дан 28 November 2019 в 05:43
поделиться

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, помощники по метаданным и т. Д.).

2
ответ дан 28 November 2019 в 05:43
поделиться

Если я правильно понял ваш вопрос, вы, по крайней мере, нарушите переносимость, напрямую реализовав джиттинг. Оставьте этот материал командам .NET, Mono или всем остальным. Так что я думаю, тебе не стоит. Но насчет части вашего вопроса "мог бы" - я думаю, вы можете пропустить IL и скомпилировать все, что захотите (насколько я знаю, MonoTouch, MonoDroid и т. Д. Делают это): Из Википедии

В отличие от приложений Mono, «Приложения» MonoTouch компилируются в машинный код, предназначенный специально для Apple iPhone.

-3
ответ дан 28 November 2019 в 05:43
поделиться

System.Reflection.Emit предоставляет средства для создания IL кода статически-типизированным способом без необходимости генерировать и компилировать текстовые файлы с IL.

3
ответ дан 28 November 2019 в 05:43
поделиться

Вы можете посмотреть здесь: http://msdn.microsoft.com/es-es/library/system.reflection.emit.aspx

0
ответ дан 28 November 2019 в 05:43
поделиться

вы можете посмотреть здесь очень простой компилятор .net:

http://msdn.microsoft.com/en-us/magazine/cc136756.aspx

0
ответ дан 28 November 2019 в 05:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: