Bytecode
En informatique, le bytecode (terme anglais signifiant « code en bytes ») est un code intermĂ©diaire entre les instructions machines et le code source, qui n'est pas directement exĂ©cutable. Le bytecode (Ă©galement appelĂ© code portable ou p-code) peut ĂȘtre crĂ©Ă© Ă la volĂ©e et rĂ©sider en mĂ©moire (compilation Ă la volĂ©e, JIT en anglais) ou bien rĂ©sider dans un fichier, gĂ©nĂ©ralement binaire qui reprĂ©sente le programme, tout comme un fichier de code objet produit par un compilateur.
Puisque c'est un code qui n'est pas exécutable directement par un processeur (à l'exception de certains processeurs gérant le bytecode Java nativement), il est utilisé par les créateurs de langages de programmation en guise de code intermédiaire réduisant la dépendance vis-à -vis du matériel et facilitant son interprétation sur plusieurs architectures.
Certains compilateurs, comme LLVM, et langages de scripts, comme SmallTalk, Java ou certaines implémentations de Ruby (telles que JRuby, Ruby.NET ou SmallRuby), utilisent le bytecode comme représentation intermédiaire avant la transformation en code machine vers l'architecture cible (x86, ARM, MIPS, etc.).
Certains systĂšmes, appelĂ©s « traducteurs dynamiques » ou « compilateurs Ă la volĂ©e » (JIT (just-in-time) compilers en anglais), traduisent le bytecode en code machine au fur et Ă mesure de lâexĂ©cution, cela permet dâaccĂ©lĂ©rer lâexĂ©cution sur les boucles ou les fonctions appelĂ©es plusieurs fois tout en Ă©vitant de stocker sur disque ou de transfĂ©rer via les rĂ©seaux des donnĂ©es prĂ©compilĂ©es. Cette technique est notamment utilisĂ©e dans le langage Java et dans les Ă©mulateurs de systĂšmes (ordinateurs ou consoles de jeu par exemple), retranscrivant les instructions d'un langage machine Ă un autre et plus gĂ©nĂ©ralement d'une architecture matĂ©rielle Ă une autre.
Un programme Ă base de bytecode est exĂ©cutĂ© par un interprĂ©teur appelĂ© machine virtuelle, car elle exĂ©cute le code tout comme un microprocesseur. L'avantage est la portabilitĂ© : le mĂȘme bytecode peut ĂȘtre exĂ©cutĂ© sur diverses plates-formes ou architectures pour lesquelles un interprĂ©teur existe. Un programme sous forme de bytecode peut donc ĂȘtre transmis d'une machine Ă une autre, et ĂȘtre interprĂ©tĂ© puis exĂ©cutĂ© sans modification de celui-ci par diffĂ©rents types d'architectures matĂ©rielles. L'avantage est le mĂȘme que pour les scripts, qui sont directement interprĂ©tĂ©s (et non compilĂ©s en bytecode). Cependant, le bytecode est plus concret, plus compact et plus facile Ă manipuler qu'un script, prĂ©vu pour ĂȘtre intelligible par l'homme. Pour ces raisons, les performances des interprĂ©teurs de bytecode sont gĂ©nĂ©ralement bien meilleures que celles des interprĂ©teurs de scripts.
Pour bĂ©nĂ©ficier de ces avantages, aujourd'hui de nombreux langages interprĂ©tĂ©s sont en fait compilĂ©s en bytecode avant d'ĂȘtre exĂ©cutĂ©s par un interprĂ©teur. C'est le cas par exemple de PHP (lorsqu'il est utilisĂ© pour des applications), de Tcl, de Python. Un programme Java est habituellement transmis sous forme de bytecode Ă une machine hĂŽte qui utilisera une compilation Ă la volĂ©e pour traduire le bytecode en code machine avant exĂ©cution. Les implĂ©mentations actuelles de Perl et de Ruby utilisent non pas du bytecode, mais une structure en arbre qui se rapproche de la reprĂ©sentation intermĂ©diaire des compilateurs.
Les p-codes diffĂšrent des bytecodes par le codage de leurs opĂ©rations, qui peut ĂȘtre de plusieurs octets avec une taille variable, tout comme les opcodes de nombreux processeurs. Ils ont un plus haut niveau descriptif, comme « afficher cette chaine de caractĂšres » ou encore « effacer l'Ă©cran ». Le BASIC et quelques versions de Pascal utilisent un p-code.
Exemples
- O-code de BCPL ;
- CLISP, une implantation de Common Lisp, ne compile qu'en bytecode ;
- CMUCL, une implantation de Common Lisp, peut compiler en bytecode ou en code natif ; le code natif est bien plus compact ;
- OCaml peut compiler un bytecode compact, mais pas seulement ; le bytecode d'OCaml et son interpréteur (ocamlrun) semblent former l'une des combinaisons les plus efficaces parmi tous les bytecodes existants ;
- Microsoft .NET Common Intermediate Language, exécuté par le Common Language Runtime ;
- Java de Sun Microsystems (voir Bytecode Java) ;
- Python, oĂč un module (fichier module.py) est compilĂ© vers du bytecode (fichier module.pyc) Ă l'importation durant l'exĂ©cution, mais pas nĂ©cessairement Ă l'exĂ©cution ;
>>> import dis #"dis" - Disassembler of Python byte code into mnemonics.
>>> dis.dis('print("Hello, World!")')
1 0 LOAD_NAME 0 (print)
2 LOAD_CONST 0 ('Hello, World!')
4 CALL_FUNCTION 1
6 RETURN_VALUE
- Le SPIN du Propeller de Parallax Inc.