.net - net - clr
¿Escribiendo un compilador para.net-IL o Bytecode? (7)
¿Por qué no usar simplemente la API Reflection.Emit para producir un ensamblaje en memoria con el código compilado y luego guardarlo en el disco? Debería ser mucho más fácil que escribir archivos .IL.
Campo de golf:
Si desea seguir este camino, si hace preguntas más específicas aquí, de modo que obtenga muchos ejemplos de cómo definir un ensamblaje dinámico y guardarlo en el disco.
Aquí hay un ejemplo:
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");
}
}
}
Puede descargar el archivo de solución de prueba desde aquí . Enlace directo al archivo zip con solución here .
Si primero compila y ejecuta este programa, producirá un nuevo archivo exe en el disco, llamado TestOutput, que luego puede ejecutar para tener "Hello World!" Impreso en la consola.
Actualmente estoy buceando en el funcionamiento interno de .net, lo que significa IL. Como ejercicio, quiero construir un compilador de brainf..k para .net (sí, ya existen, pero como he dicho es para fines de aprendizaje).
Por el momento solo escribo algunos archivos de texto que contienen .il y los compila con ilasm, que funciona. Pero me pregunto si podría / debería ir un nivel más profundo y escribir el código de bytes directamente.
Mi "preocupación" es el Windows PE Stuff al compilar un EXE. En lugar de ilasm, ¿necesitaría algún tipo de vinculador de Bytecode que tomaría mi bytecode MSIL / CIL y generaría el PE Stuff?
¿O los compiladores "solo" compilan su lenguaje en IL y ejecutan ilasm? ¿Hay una versión administrada de la que puedo llamar / incrustar desde mi compilador?
Con el nuevo DLR uno debería poder crear código utilizando clases .Net. No estoy seguro de cuánto lo protege de la IL / bytecode real, ya que esto es lo que está tratando de aprender.
Puede mirar allí: http://msdn.microsoft.com/es-es/library/system.reflection.emit.aspx
Puedes mirar un compilador .net muy simple allí:
Reflexión. Emisión será más directa para sus propósitos, pero es posible que también desee ver el proyecto de infraestructura de compilador común en CodePlex.
Aquí está el resumen de la página del proyecto para ese proyecto:
Microsoft Research Common Compiler Infrastructure (CCI) es un conjunto de bibliotecas y una interfaz de programación de aplicaciones (API) que admite algunas de las funciones que son comunes a los compiladores y las herramientas de programación relacionadas.
La API de metadatos de CCI permite que las aplicaciones analicen o modifiquen de manera eficiente los ensamblados, módulos y archivos de depuración (PDB) de .NET. CCI Metadata admite la funcionalidad de las API .NET System.Reflection y System.Reflection.Emit, pero con un rendimiento mucho mejor. También proporciona funcionalidad adicional que no está disponible en ninguna API .NET.
Ese proyecto tiene un PeWriter / PeReader entre todas las otras cosas que necesitarías para escribir un compilador .net (ILGenerator, ayudantes de metadatos, etc.).
Si entendí tu pregunta correctamente, al menos violarás la portabilidad, implementando jitting directamente. Deja esto para .NET, Mono, cualquier equipo. Así que creo que no deberías. Pero sobre una parte de su pregunta sobre ''podría'', creo que puede omitir IL y compilar en lo que quiera (por lo que sé, MonoTouch, MonoDroid, etc.): De Wikipedia
A diferencia de las aplicaciones Mono, las "Aplicaciones" MonoTouch se compilan en un código de máquina dirigido específicamente al iPhone de Apple.
System.Reflection.Emit
proporciona facilidades para crear código IL de forma estática sin tener que generar y compilar archivos de texto con IL.