El código de bytes (también llamado código portátil o código p ) es un conjunto de instrucciones diseñado para una ejecución eficiente por un intérprete de software . A diferencia del código fuente legible por humanos [ 1 ] , los códigos de bytes son códigos numéricos compactos, constantes y referencias (normalmente direcciones numéricas) que codifican el resultado del análisis sintáctico del compilador y realizan un análisis semántico de aspectos como el tipo, el ámbito y la profundidad de anidamiento de los objetos del programa.
El término bytecode proviene de conjuntos de instrucciones que utilizan códigos de operación de un byte seguidos de parámetros opcionales. Las implementaciones de lenguajes de programación pueden generar representaciones intermedias, como el bytecode, para facilitar la interpretación , o bien, utilizarlo para reducir la dependencia del hardware y del sistema operativo, permitiendo que el mismo código se ejecute en diferentes plataformas y dispositivos. El bytecode suele ejecutarse directamente en una máquina virtual (un intérprete de código P ) o bien se compila en código máquina para un mejor rendimiento.
Dado que las instrucciones de código de bytes son procesadas por software, pueden ser arbitrariamente complejas, pero aun así suelen ser similares a las instrucciones de hardware tradicionales: las máquinas de pila virtual son las más comunes, pero también se han construido máquinas de registro virtual. [ 2 ] [ 3 ] Las diferentes partes a menudo se almacenan en archivos separados, de forma similar a los módulos de objetos , pero se cargan dinámicamente durante la ejecución.
Ejecución
Un programa de bytecode puede ejecutarse analizando y ejecutando directamente las instrucciones, una a una. Este tipo de intérprete de bytecode es muy portable. Algunos sistemas, llamados traductores dinámicos o compiladores justo a tiempo (JIT), traducen el bytecode a código máquina según sea necesario en tiempo de ejecución . Esto hace que la máquina virtual sea específica del hardware, pero no pierde la portabilidad del bytecode. Por ejemplo, el código Java y Smalltalk se almacena normalmente en formato de bytecode, que luego se compila mediante JIT para traducirlo a código máquina antes de su ejecución. Esto introduce un retraso antes de que se ejecute un programa, cuando el bytecode se compila a código máquina nativo, pero mejora considerablemente la velocidad de ejecución en comparación con la interpretación directa del código fuente, normalmente en un orden de magnitud (10x). [ 4 ]
Debido a su ventaja en rendimiento, hoy en día muchas implementaciones de lenguajes ejecutan un programa en dos fases: primero compilan el código fuente a bytecode y luego pasan el bytecode a la máquina virtual. Existen máquinas virtuales basadas en bytecode de este tipo para Java , Raku , Python , PHP , Tcl , mawk y Forth ( sin embargo, Forth rara vez se compila mediante bytecode de esta manera, y su máquina virtual es más genérica). La implementación de Perl y Ruby 1.8 , en cambio , funciona recorriendo una representación abstracta del árbol de sintaxis derivada del código fuente.
Más recientemente, los autores de V8 [ 1 ] y Dart [ 7 ] han cuestionado la idea de que se necesite un código de bytes intermedio para una implementación de máquina virtual rápida y eficiente. Ambas implementaciones de lenguaje actualmente realizan compilación JIT directa desde el código fuente a código máquina sin un intermediario de código de bytes. [ 8 ] Por ejemplo, las primeras versiones del motor JavaScript V8 omitieron deliberadamente una capa intermedia de código de bytes, realizando compilación JIT directa desde el texto fuente directamente a código máquina nativo a través de su compilador "Full-codegen". [ 9 ]
Sin embargo, esta arquitectura se enfrentó a un grave problema de sobrecarga de memoria en dispositivos móviles y a una complejidad inmanejable al admitir las nuevas y complejas especificaciones de ECMAScript. Como resultado, V8 renovó por completo su canalización de ejecución en 2017, introduciendo un intérprete de código de bytes basado en registros de bajo nivel llamado "Ignition". Las versiones modernas de V8 ahora dependen en gran medida del código de bytes intermedio como su nivel de ejecución fundamental, elevando gradualmente las funciones "calientes" del código de bytes a una arquitectura JIT de código máquina nativo de múltiples niveles (Sparkplug, Maglev y TurboFan). [ 10 ]
Ejemplos
- ActionScript se ejecuta en la máquina virtual de ActionScript (AVM), que forma parte de Flash Player y AIR . El código ActionScript se transforma normalmente en formato de bytecode mediante un compilador . Algunos ejemplos de compiladores son el integrado en Adobe Flash Professional y el integrado en Adobe Flash Builder, disponible en el SDK de Adobe Flex .
- Objetos de Adobe Flash
- BANCStar , originalmente código de bytes para una herramienta de creación de interfaces, pero también utilizado como lenguaje.
- Filtro de paquetes de Berkeley
- EBPF
- Berkeley Pascal [ 11 ]
- Biblioteca de ingeniería de código de bytes
- Compiladores de máquina virtual de C a Java
- La implementación CLISP de Common Lisp solía compilar solo a bytecode durante muchos años; sin embargo, ahora también admite la compilación a código nativo con la ayuda de GNU Lightning.
- Las implementaciones de Common Lisp de CMUCL y Scieneer pueden compilarse tanto a código nativo como a bytecode, que es mucho más compacto.
- Lenguaje Intermedio Común ejecutado por Common Language Runtime , utilizado por lenguajes .NET como C#.
- El código de bytes de Dalvik , diseñado para la plataforma Android , es ejecutado por la máquina virtual Dalvik.
- El código de bytes Dis, diseñado para el sistema operativo Inferno , es ejecutado por la máquina virtual Dis.
- EiffelStudio para el lenguaje de programación Eiffel
- EM, la máquina virtual del Amsterdam Compiler Kit, se utiliza como lenguaje de compilación intermedio y como lenguaje de bytecode moderno.
- Emacs es un editor de texto cuyas funciones están implementadas principalmente en Emacs Lisp , su dialecto integrado de Lisp . Estas características se compilan en código de bytes. Esta arquitectura permite a los usuarios personalizar el editor con un lenguaje de alto nivel que, tras compilarse en código de bytes, ofrece un rendimiento aceptable.
- Implementación integrable de Common Lisp. Common Lisp puede compilarse a código de bytes o código C.
- Common Lisp proporciona una
disassemblefunción [ 12 ] que imprime en la salida estándar el código subyacente de una función específica. El resultado depende de la implementación y puede o no resolverse en bytecode. Su inspección puede utilizarse para fines de depuración y optimización. [ 13 ] Por ejemplo, Steel Bank Common Lisp produce:
( desensamblar ' ( lambda ( x ) ( imprimir x ))) ; desensamblaje para (LAMBDA (X)) ; 2436F6DF: 850500000F22 TEST EAX, [#x220F0000] ; punto de entrada sin análisis de argumentos ; E5: 8BD6 MOV EDX, ESI ; E7: 8B05A8F63624 MOV EAX, [#x2436F6A8] ; #<objeto FDEFINITION para PRINT> ; ED: B904000000 MOV ECX, 4 ; F2: FF7504 PUSH DWORD PTR [EBP+4] ; F5: FF6005 JMP DWORD PTR [EAX+5] ; F8: CC0A BREAK 10 ; trampa de error ; FA: 02 BYTE #X02 ; FB: 18 BYTE #X18 ; INVALID-ARG-COUNT-ERROR ; FC: 4F BYTE #X4F ; ECX
- La implementación de Erlang por parte de Ericsson utiliza códigos de bytes BEAM.
- La Máquina Virtual de Ethereum (EVM) es el entorno de ejecución, que utiliza su propio código de bytes, para la ejecución de transacciones en Ethereum (contratos inteligentes).
- Lenguajes de programación Icon [ 14 ] y Unicon [ 15 ]
- Infocom utilizó la máquina Z para hacer que sus aplicaciones de software fueran más portátiles.
- Código de bytes de Java , que es ejecutado por la máquina virtual de Java.
- El código de bytes Keiko es utilizado por el lenguaje de programación Oberon-2 para hacer que tanto este como el sistema operativo Oberon sean más portátiles.
- KEYB , el controlador de teclado MS-DOS / PC DOS con su archivo de recursos KEYBOARD.SYS que contiene información de diseño y secuencias cortas de código p ejecutadas por un intérprete dentro del controlador residente. [ 16 ] [ 17 ]
- LLVM IR
- LSL, un lenguaje de scripting utilizado en mundos virtuales, se compila en código de bytes que se ejecuta en una máquina virtual. Second Life tiene la versión original Mono, mientras que Inworldz desarrolló la versión Phlox.
- El lenguaje Lua utiliza una máquina virtual de código de bytes basada en registros.
- Código M del lenguaje MATLAB [ 18 ]
- Malbolge es un lenguaje de máquina esotérico para una máquina virtual ternaria.
- Código P de Microsoft utilizado en Visual C++ y Visual Basic.
- Multiplan [ 19 ]
- Código O del lenguaje de programación BCPL
- El lenguaje OCaml se compila opcionalmente a un formato de código de bytes compacto.
- Código P de la implementación Pascal de UCSD del lenguaje Pascal
- Máquina virtual Parrot
- Pick BASIC también conocido como Data BASIC o MultiValue BASIC
- El entorno R para computación estadística ofrece un compilador de código de bytes a través del paquete compiler, que ahora viene incluido de serie en la versión 2.13.0 de R. Es posible compilar esta versión de R para que los paquetes base y recomendados aprovechen esta funcionalidad. [ 20 ]
- Juego de aventuras Pyramid 2000
- Los scripts de Python se compilan al ejecutarse en el lenguaje de bytecode de Python, y los archivos compilados (.pyc) se almacenan en caché dentro de la carpeta del script.
- El código compilado se puede analizar e investigar utilizando una herramienta integrada para depurar el código de bytes de bajo nivel. La herramienta se puede inicializar desde la consola, por ejemplo:
>>> import dis # "dis" - Desensamblador de código de bytes de Python en mnemónicos. >>> dis . dis ( 'print("¡Hola, mundo!")' ) 1 0 LOAD_NAME 0 (print) 2 LOAD_CONST 0 ('¡Hola, mundo!') 4 CALL_FUNCTION 1 6 RETURN_VALUE
- Implementación de Scheme mediante intérprete de código de bytes (Scheme 48)
- Códigos de bytes de muchas implementaciones del lenguaje Smalltalk
- El intérprete Spin integrado en el microcontrolador Parallax Propeller
- El motor de base de datos SQLite traduce las sentencias SQL a un formato de código de bytes personalizado. [ 21 ]
- Manzana DULCE16
- Tcl
- TIMI es utilizado por los compiladores en la plataforma IBM i .
- Tiny BASIC
- Visual Basic para Aplicaciones se compila a código de bytes.
- Visual FoxPro compila a código de bytes
- WebAssembly
- YARV y Rubinius para Ruby
- Código Z
- Códigos de operación de Zend Engine para PHP
Véase también
- Plataforma informática : entorno en el que se ejecuta un programa informático.
- Representación intermedia : estructura de datos o código utilizado por un compilador.
- Sistema de ejecución : sistema informático que proporciona el comportamiento necesario para la ejecución del código.
Notas
- ↑ PHP tiene compilación just-in-time en PHP 8, [ 5 ] [ 6 ] y antes, aunque no estaba activada en la versión predeterminada, tenía opciones como HHVM . Para versiones anteriores de PHP: Aunque los códigos de operación de PHP se generan cada vez que se inicia el programa, siempre se interpretan y no se compilan just-in-time .
Referencias
- 1 2 "Generación dinámica de código máquina" . Google Inc. Archivado del original el 5 de marzo de 2017. Recuperado el 1 de diciembre de 2024 .
- ↑ "La implementación de Lua 5.0" .(Nota: Esto implica una máquina virtual basada en registros).
- ↑ "Dalvik VM" . Archivado del original el 18 de mayo de 2013. Consultado el 29 de octubre de 2012 .(Nota: Esta máquina virtual se basa en registros).
- ↑ "Código de bytes frente a código máquina" . www.allaboutcomputing.net . Consultado el 23 de octubre de 2017 .
- ↑ O'Phinney, Matthew Weier. "Explorando el nuevo compilador JIT de PHP" . Zend by Perforce . Consultado el 19 de febrero de 2021 .
- ↑ "PHP 8: El JIT - stitcher.io" . stitcher.io . Consultado el 19 de febrero de 2021 .
- ↑ Loitsch, Florian. "¿Por qué no una máquina virtual de código de bytes?" . Google . Archivado del original el 12 de mayo de 2013.
- ↑ "Mito de JavaScript: JavaScript necesita un código de bytes estándar" . 2ality.com . Archivado del original el 20 de junio de 2018.
- ↑ Wingo, Andy (2011-07-05). "v8: una historia de dos compiladores" . wingolog.org . Consultado el 2026-07-05 .
- ↑ McIlroy, Ross (15 de mayo de 2017). "Lanzamiento de Ignition y TurboFan" . v8.dev . Proyecto Google V8 . Consultado el 5 de julio de 2026 .
- ↑ G., Adam Y. (11 de julio de 2022). "Berkeley Pascal" . GitHub . Recuperado el 8 de enero de 2022 .
- ↑ "CLHS: Función DESMONTAR" . www.lispworks.com .
- ↑ Collective (13-12-2023). "The Common Lisp Cookbook – Performance Tuning and Tips" . lispcookbook.github.io .
- ↑ "La implementación del lenguaje de programación Icon" (PDF) . Archivado del original (PDF) el 5 de marzo de 2016. Consultado el 9 de septiembre de 2011 .
- ↑ "La implementación de Icon y Unicon: un compendio" (PDF) . Archivado (PDF) del original el 9 de octubre de 2022.
- ↑ Paul, Matthias R. (30/12/2001). "Estructura interna de KEYBOARD.SYS" . Grupo de noticias : comp.os.msdos.programmer . Consultado el 17/09/2016 .
[…] De hecho, el formato es básicamente el mismo en
MS-DOS
3.3
- 8.0,
PC DOS
3.3
- 2000, incluyendo las versiones en ruso, lituano, chino y japonés, así como en Windows NT, 2000 y XP […]. Existen pequeñas diferencias e incompatibilidades, pero el formato general no ha cambiado a lo largo de los años. […] Algunas de las entradas de datos contienen tablas normales […] Sin embargo, la mayoría de las entradas contienen
código ejecutable
interpretado por algún tipo de
intérprete de código P
en *
tiempo de ejecución
*, incluyendo bifurcaciones condicionales y similares. Por eso, el controlador
KEYB
tiene un consumo de memoria tan elevado en comparación con los controladores de teclado basados en tablas, que pueden funcionar con 3-4 KB, obteniendo el mismo nivel de funcionalidad, excepto por el intérprete. […]
{{cite newsgroup}}: CS1 maint: servicio de archivado obsoleto ( enlace ) - ↑ Mendelson, Edward (2001-07-20). "Cómo mostrar el euro en MS-DOS y Windows DOS" . Mostrar el símbolo del euro en MS-DOS a pantalla completa (incluido Windows 95 o Windows 98 DOS a pantalla completa). Archivado del original el 17-09-2016 . Recuperado el 17-09-2016 .
[…] Matthias [R.] Paul […] advierte que la versión
para IBM PC DOS
del controlador de teclado utiliza algunos procedimientos internos que no son reconocidos por el controlador
de Microsoft
, por lo que, si es posible, debería usar las versiones
de IBM
tanto de
KEYB.COM
como
de KEYBOARD.SYS
en lugar de mezclar las versiones de Microsoft e IBM […]
(Nota: Lo que se entiende aquí por "procedimientos" son algunos códigos de bytes adicionales en el archivo IBM KEYBOARD.SYS que no son compatibles con la versión de Microsoft del controlador KEYB).
- ↑ "Patente de Estados Unidos 6,973,644" . Archivado del original el 5 de marzo de 2017. Consultado el 21 de mayo de 2009 .
- ↑ Especificaciones de Microsoft C Pcode . pág. 13.
Multiplan
no se compiló a
código máquina
, sino a una especie de código de bytes que era ejecutado por un
intérprete
, para que Multiplan fuera portable a través del hardware tan diverso de la época. Este código de bytes distinguía entre el
formato de punto flotante
específico de la máquina para realizar los cálculos y un formato externo (estándar), que era
el decimal codificado en binario
(BCD). Las instrucciones PACK y UNPACK convertían entre ambos.
- ↑ "Instalación y administración de R" . cran.r-project.org .
- ↑ "El motor de código de bytes SQLite" . Archivado del original el 14 de abril de 2017. Consultado el 29 de agosto de 2016 .
- Códigos de bytes
- Virtualización