Подтвердить что ты не робот

Написание компилятора для .net - IL или Bytecode?

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

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

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

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

4b9b3361

Ответ 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/байт-кода, так как это то, что вы пытаетесь изучить.

Ответ 7

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

В отличие от приложений Mono MonoTouch "Приложения" скомпилированы до машинного кода, ориентированного именно на Apple iPhone.