Compilar MSIL a código nativo

Para poder ejecutar el lenguaje intermedio de Microsoft (MSIL), primero se debe convertir éste, mediante un compilador Just-In-Time (JIT) de .NET Framework, a código nativo, que es el código específico de la CPU que se ejecuta en la misma arquitectura de equipo que el compilador JIT. Common Language Runtime proporciona un compilador JIT para cada arquitectura de CPU compatible, por lo que los programadores pueden escribir un conjunto de MSIL que se puede compilar mediante un compilador JIT y ejecutar en equipos con diferentes arquitecturas. No obstante, el código administrado sólo se ejecutará en un determinado sistema operativo si llama a las API nativas específicas de la plataforma o a una biblioteca de clases específica de la plataforma.

La compilación JIT tiene en cuenta el hecho de que durante la ejecución nunca se llamará a parte del código. En vez de utilizar tiempo y memoria para convertir todo el MSIL de un archivo ejecutable portable (PE) a código nativo, convierte el MSIL necesario durante la ejecución y almacena el código nativo resultante para que sea accesible en las llamadas posteriores. El cargador crea y asocia un código auxiliar a cada uno de los métodos del tipo cuando éste se carga. En la llamada inicial al método, el código auxiliar pasa el control al compilador JIT, el cual convierte el MSIL del método en código nativo y modifica el código auxiliar para dirigir la ejecución a la ubicación del código nativo. Las llamadas posteriores al método compilado mediante un compilador JIT pasan directamente al código nativo generado anteriormente, reduciendo el tiempo de la compilación JIT y la ejecución del código.

El motor en tiempo de ejecución proporciona otro modo de compilación denominado generación de código en el momento de la instalación. El modo de generación de código en el momento de la instalación convierte el MSIL a código nativo, tal y como lo hace el compilador JIT normal, aunque convierte mayores unidades de código a la vez, almacenando el código nativo resultante para utilizarlo posteriormente al cargar y ejecutar el ensamblado. Cuando se utiliza el modo de generación de código durante la instalación, todo el ensamblado que se está instalando se convierte a código nativo, teniendo en cuenta las características de los otros ensamblados ya instalados. El archivo resultante se carga e inicia más rápidamente que si se hubiese convertido en código nativo con la opción JIT estándar.

Como parte de la compilación MSIL en código nativo, el código debe pasar un proceso de comprobación, a menos que el administrador haya establecido una directiva de seguridad que permita al código omitir esta comprobación. En esta comprobación se examina el MSIL y los metadatos para determinar si el código garantiza la seguridad de tipos, lo que significa que el código sólo tiene acceso a aquellas ubicaciones de la memoria para las que está autorizado. La seguridad de tipos ayuda a aislar los objetos entre sí y, por tanto, ayuda a protegerlos contra daños involuntarios o maliciosos. Además, garantiza que las restricciones de seguridad sobre el código se aplican con toda certeza.

El motor en tiempo de ejecución se basa en el hecho de que se cumplan las siguientes condiciones para el código con seguridad de tipos comprobable:

  • La referencia a un tipo es estrictamente compatible con el tipo al que hace referencia.

  • En un objeto sólo se invocan las operaciones definidas adecuadamente.

  • Una identidad es precisamente lo que dice ser.

Durante el proceso de comprobación, se examina el código MSIL para intentar confirmar que el código tiene acceso a las ubicaciones de memoria y puede llamar a los métodos sólo a través de los tipos definidos correctamente. Por ejemplo, un código no permite el acceso a los campos de un objeto si esta acción sobrecarga las ubicaciones de memoria. Además, el proceso de comprobación examina el código para determinar si el MSIL se ha generado correctamente, ya que un MSIL incorrecto puede llevar a la infracción de las reglas en materia de seguridad de tipos. El proceso de comprobación pasa un conjunto de código con seguridad de tipos definido correctamente, y pasa de forma exclusiva código con seguridad de tipos. No obstante, algunos códigos con seguridad de tipos no pasan la comprobación debido a las limitaciones de este proceso, y algunos lenguajes no producen código con seguridad de tipos comprobable debido a su diseño. Si la directiva de seguridad requiere código con seguridad de tipos y el código no pasa la comprobación, se produce una excepción al ejecutar el código.

Vea también

Conceptos

Proceso de ejecución administrada