Table des matières

Introduction
Abstract
But du projet
Cadre administratif
Avantages et applications
Structure du rapport
Partie théorique
Le deux plates-formes
Traduction des structures des deux bytecodes
Traduction des instructions
Implémentation
Introduction
Parcours des technologies existantes, choix effectués
Structure du traducteur, description de l'implémentation
Limitations d'implémentations
Conclusions, tests
Références

Introduction

Abstract

Certains récents langages de programmation répandus comme Java et C# utilisent la notion de machine virtuelle. Ils sont compilés vers une forme intermédiaire basée sur une définition de machine abstraite.

Pour le langage Java développé par Sun, la forme intermédiaire est le bytecode Java. Dernièrement, la plate-forme .Net développée par Microsoft utilise aussi un tel format intermédiaire connu sous le nom de "Common Intermediate Language" (abrégé Cil).

Etant donné que les deux formats intermédiaires sont relativement similaires, il serait intéressant de pouvoir passer d'un format à l'autre par le biais d'une traduction.

But du projet

Le but de ce projet est d'étudier et réaliser un traducteur de bytecode Java vers du bytecode .Net.

Cadre administratif

Ce projet est réalisé lors du 7ème semestre (hivers 2002/2003) au laboratoire des Méthodes de Programmation du Département d'informatique de l'EPFL, sous la conduite du professeur Martin Odersky. L'assistant responsable du suivi du projet est Philippe Altherr.

Avantages et applications

L'utilisation d'une machine virtuelle et la production de code intermédiaire par un compilateur a déjà été utilisé à plusieurs reprises dans le passé. Cette façon de faire présente plusieurs avantages en comparaison à une compilation native:

  • Portabilité: Le code intermédiaire est identique sur toutes les architectures qui interprètent ce code par une machine virtuelle. C'est l'argument principal du succès du langage Java.

  • Sécurité: Le fait d'avoir une forme intermédiaire interprétée permet de contrôler exactement l'accès aux ressources d'un programme. Ceci permet de pouvoir exécuter du code non sûr (on peut par exemple restreindre l'accès au système de fichier pour les programmes téléchargés sur Internet). La sécurité est un élément clé des plates-formes .Net et Java. Pour cette dernière, un exemple connu est celui des des "Applets Java". Les "Applets" sont des programmes Java généralement de petite taille qui tournent dans des navigateurs Web.

  • Possibilités d'optimisation: Le fait d'interpréter du code intermédiaire implique une baisse de performances. Les machines virtuelles récentes utilisent des compilateurs "Just In Time" (JIT) qui traduisent dynamiquement le code intermédiaire en code natif, pour qu'il s'exécute plus rapidement. L'avantage d'avoir du code intermédiaire est qu'il est possible de bénéficier des améliorations de performance des machines virtuelles sans devoir recompiler le code source, ce qui n'est pas possible avec une compilation native.

  • Stockage de méta données (Metadata): Le code intermédiaire ne dépendant pas d'un processeur spécifique, il est possible de stocker des données annexes dans les exécutables. Cet aspect est utilisé dans la plate-forme .Net pour stocker divers types de méta données dans le code intermédiaire, telle que le nom des champs, des données pour la sérialisation, etc.

Il est légitime de se demander à quoi peut servir d'écrire un traducteur entre les formats intermédiaires des deux plates-formes, car on peut penser qu'il serait plus utile d'écrire un compilateur Java qui émet du code Cil directement. Un tel compilateur facilite la phase de développement de code Java sur .Net. En effet, comme il a accès directement à toutes les classes, types et membres .Net, il peut détecter immédiatement les erreurs sémantiques.

Cependant, un traducteur de bytecode présente deux avantages principaux:

  • Il permet d'être indépendant du langage qui produit le bytecode. Bien que la plate-forme Java a été conçue et est supportée par Sun pour ne compiler que du code Java, de nombreux autres projets produisent aussi du bytecode Java. Citons notamment le langage Pico développé par Mathias Zenger au laboratoire Lamp de l'Epfl, ainsi que les nombreux langages référencés sur Programming Languages for the Java Virtual Machine [[VmLang]]. L'approche traducteur de bytecode permet ainsi de pouvoir traduire tout type de bytecode, indépendamment du langage qui à été utilisé pour le produire.

  • Il est relativement simple à réaliser: les deux bytecodes sont basés sur un modèle de machine à pile. Ils sont donc très similaires, et une grande partie des instructions peut se traduire aisément. Cependant, la traduction n'est pas toujours évidente, et pose parfois certains problèmes complexes, comme nous le verrons plus tard.

Dans le prochain chapitre, les deux codes intermédiaires de Java et de .Net seront étudiés plus en détail, par rapport à leur historique, points communs et différences.

Structure du rapport

Le présent rapport est divisé en deux parties majeures:

  • Partie théorique: Cette partie détaille les procédés de traduction. Elle donne les algorithmes et les explications théoriques des différents choix. Elle tente d'être indépendante de l'implémentation, de façon à ne pas poser trop de contraintes sur les implémentations possibles.

  • Partie implémentation: Cette partie explique dans le détail les technologies utilisées pour l'implémentation du traducteur. Elle explique les choix techniques effectués, et donne les limitations du traducteur.