Traducteur de byte code Java en byte code .Net

38
Traducteur de byte code Java en byte code .Net Sylvain Pasche EPFL 2003

description

Traducteur de byte code Java en byte code .Net. Sylvain Pasche EPFL 2003. Introduction. But: Réaliser un traducteur de byte code Java en byte code .Net. Fichiers .class Java. Fichiers .exe .Net. Déroulement. Partie théorique: algorithmes de traduction - PowerPoint PPT Presentation

Transcript of Traducteur de byte code Java en byte code .Net

Page 1: Traducteur de byte code Java en byte code .Net

Traducteur de byte code Java en byte code .Net

Sylvain Pasche

EPFL 2003

Page 2: Traducteur de byte code Java en byte code .Net

Introduction

But: Réaliser un traducteur de byte code Java en byte code .Net

Fichiers .class Java Fichiers .exe .Net

Page 3: Traducteur de byte code Java en byte code .Net

Déroulement

1. Partie théorique: algorithmes de traduction

2. Partie implémentation: réalisation du traducteur

Page 4: Traducteur de byte code Java en byte code .Net

Java .NetSun en 1995Format intermédiaire: byte code JavaMachine à pileByte code conçu pour le langage Java

8 types

Microsoft en 2001Format intermédiaire: byte code .NetMachine à pileByte code conçu pour être indépendant du langage (C#, J#, VB.net, …). 17 types

Les deux plates-formes

Page 5: Traducteur de byte code Java en byte code .Net

Partie théorique: approche « Top down »

Paquetages en assemblages Classes Méthodes et champs Instructions

Page 6: Traducteur de byte code Java en byte code .Net

Java .Net

Classes organisées en paquetages

Classes organisées en assemblages

Traduction des paquetages

package org.epfl; class Foo class Bar

Assembly MyAssembly class Foo class Bar

org.epfl MyAssembly

Page 7: Traducteur de byte code Java en byte code .Net

Traduction des classes Cas général: gardent le même nom

Cas spéciaux:

Objets auxiliaires pour rediriger les méthodes

java.lang.Object System.Object

java.lang.String System.String

java.lang.String trim()

JavaStringWrapper trim()

java.lang.Long java.lang.Long

Page 8: Traducteur de byte code Java en byte code .Net

Traduction des instructions Algorithme général: traduction locale On peut catégoriser les instructions en

deux classes:1. Triviales: traduction locale directe

2. non triviales

iadd, ladd add

iinc ??? (pas d’équivalent)

Page 9: Traducteur de byte code Java en byte code .Net

Instructions à traduction triviale

arithmétiques*add, *sub, *mul, *div, *rem, …

conversioni2l, i2f, ...

comparaison*cmpg, *cmpg

autresnop, monitorenter, monitorexit, …

exemple:traduction de imul:

imul mul

Page 10: Traducteur de byte code Java en byte code .Net

Instructions non triviales

Instructions d’accès aux paramètres et variables locales

Exceptions Aperçu des autres algorithmes

Page 11: Traducteur de byte code Java en byte code .Net

Instructions d’accès aux paramètres et variables locales

Java .Netparamètres + variables locales paramètres

variables locales

0 intdouble

1 float String

2 floatint

char

para

mèt

reva

riabl

es lo

cale

s

0 int

0 float

1 String

1 double

instructions: *load, *store

instructions: ldarg, starg

instructions: ldloc, stloc

Page 12: Traducteur de byte code Java en byte code .Net

Paramètres et variables locales: algorithme Les « slots » Java ne sont pas typés,

alors qu’ils le sont en .Net Java mêmes slots pour arguments et

variables locales1. Analyse des types stockés dans les slots2. Allocation des variables locales et

arguments .Net3. Lors de la production du code,

sélectionner la bonne instruction (variable loc / argument) + le slot .Net

Page 13: Traducteur de byte code Java en byte code .Net

Exceptions

Un bloc Java Un bloc .Net

try start = 0x12

try end = 0x21

catch start = 0x23

catch end = ???

finally start = 0x34

finally end = ???

try start = 0x14

try end = 0x20

catch start = 0x22

catch end = 0x27

finally start = 0x30

finally end = 0x40Java contient moins d’information sur les blocs d’exception.

Il faut retrouver cette information

Page 14: Traducteur de byte code Java en byte code .Net

Reconstituer les blocs: tâche difficile Java pose très peu de contraintes sur

l’emplacement des blocs L’algorithme général très complexe Simplification: blocs dans l’ordre

try starttry end

catch startcatch end

finally startfinally end

facile à calculer

plus difficile à trouver

Page 15: Traducteur de byte code Java en byte code .Net

Algorithme de reconstitution des blocs Algorithme basé sur des expérimentations Principe: analyser les sauts pour en

déduire la fin des blocs Marche bien dans la plupart des cas,

moins bien dans les situations complexes (imbrications, …)

Page 16: Traducteur de byte code Java en byte code .Net

Autres algorithmes Pas de temps pour tous les voir:

instructions de création d’objets instructions d’appel de méthodes instructions d’accès aux champs instructions de branchement instructions de manipulation de la pile

Page 17: Traducteur de byte code Java en byte code .Net

Scénario 1Scénario 2

Partie 2: implémentation

Java .Net

Librairie lecture bytecode Java

JikesBt

gnu.bytecode

BCEL

Ø

librairie écriture bytecode .Net

Msil System.Refle-ction.Emit

Page 18: Traducteur de byte code Java en byte code .Net

Librairie BCEL

« Byte Code Engineering Library » Offre beaucoup de fonctionnalités

avancées Un vérificateur, mais ne permet pas

d’accéder aux informations des types:Modifications de la librairie pour permettre d’

extraire ces informations

Page 19: Traducteur de byte code Java en byte code .Net

Libraire Msil (1)

Développée par Laurent Rolaz au LAMP S’inspire de System.Reflection.Emit, mais

écrite en Java Petit sous ensemble des fonctionnalités de

System.Reflection.Emit Génère un fichier texte d’instructions qui

doit ensuite être assemblé

Page 20: Traducteur de byte code Java en byte code .Net

Librairie Msil (2)

Librairie peu testée:Corrections des bugs à faire

Fonctionnalités limitées:Ajout de nouvelles fonctionnalités pour le

traducteur

Page 21: Traducteur de byte code Java en byte code .Net

Le traducteur: Java2il

http://java2il.sourceforge.net

Implémente tous les algorithmes partie théorique Gère plusieurs formats en entrée (.jar, .class, …) Interface ligne de commande simple et intuitive Fichiers de configuration pour gérer les

paramètres

Page 22: Traducteur de byte code Java en byte code .Net

Interface ligne de commande

java2il --assembly Hello --entrypoint Main Hello.class java.util.Date myjar.jar

(facultatif)nom de l’assemblage traduit

(facultatif)nom de la classe du point d’entrée

nom des classes à traduire:Fichiers .classFichiers .jarnom de classes Java

Page 23: Traducteur de byte code Java en byte code .Net

Fichiers de configuration

Correspondance paquetages Java et assemblages .Net

spécifie pour chaque paquetage Java le nom de l’assemblage .Net traduit

Options de traduction:

Niveau de déboguage Quels sont les objets

qui redirigent les méthodes de java.lang.Object et java.lang.String

Page 24: Traducteur de byte code Java en byte code .Net

Limitations

Les limitations sont celles posées par les algorithmes

La traduction des exceptions pose parfois problème ne parvient pas à trouver les bornes des blocs

d’exception dans les cas compliqués (imbrications multiples)

La traduction de certaines instructions pourrait être optimisée

Page 25: Traducteur de byte code Java en byte code .Net

Conclusion

Succès ! le but est atteint

Tests concluants effectués sur le compilateur Misc

La traduction peut paraître simple, mais des problème complexes se posent

Page 26: Traducteur de byte code Java en byte code .Net

Questions ?

Page 27: Traducteur de byte code Java en byte code .Net

Traduction des classes: cas de java.lang.Object et java.lang.String

java.lang.Object System.Object

Scénario choisi:

java.lang.String System.String

java.lang.String trim()

JavaStringWrapper trim()

Il faudra rediriger les méthodes appelées sur ces objets avec des classes auxiliaires:

Page 28: Traducteur de byte code Java en byte code .Net

Traduction des classes: cas de java.lang.Object

java.lang.Object

System.Object

java.lang.Object

System.Object

?scénario 1

scénario 2

Page 29: Traducteur de byte code Java en byte code .Net

Traduction des méthodes Cas général: même nom Si on traduit java.lang.String en

System.String, il faut rediriger certaines méthodes. De même pour java.lang.Object

Pour se faire, on utilise des classes auxiliaire:java.lang.String trim()

JavaStringWrapper trim()

Page 30: Traducteur de byte code Java en byte code .Net

Java .Net

new java.util.Date

dup

invokespecial

java.util.Date.<init>

newobj java.util.Date

Instructions de création d’objets

L’algorithme simpliste consiste à ignorer les instructions new et dup, et traduire inovkespecial en newobj

Page 31: Traducteur de byte code Java en byte code .Net

Cas particuliers: les objets dans les slots Java

ldstr « a_string »

astore 1

new java.util.Date

astore 1 Faut-il utiliser deux slots .Net ?

1 java.lang.String

2 java.util.Date

Page 32: Traducteur de byte code Java en byte code .Net

Instructions de manipulation de la pile Java comporte beaucoup d’instructions de

manipulation de la pile, absente en .Netpop, dup, pop2, dup_x1, dup_x2, dup2,

dup2_x1, dup2_x2, swap Comment les traduire ?

Une solution est d’utiliser les variables locales, et faire des empilements et dépilements

Page 33: Traducteur de byte code Java en byte code .Net

Instructions de manipulation de la pile: exemple (1) instruction dup_x2

Il faut d’abord analyser quelle forme considérer

1 1/2 1

1 1

2

1 1

11

haut

de

la p

ile

bas

de la

pile

Forme 1

Forme 2

Page 34: Traducteur de byte code Java en byte code .Net

Instructions de manipulation de la pile: exemple (2) instruction dup_x2 (forme 1)

1 1 1 1 11 1

haut

de

la p

ile

bas

de la

pile Forme 1

1) stockage variables locales

stloc 1

stloc 2

stloc 3

2) dépilement sur la pile

ldloc 1

ldloc 3

ldloc 2

ldloc 1

état des variables locales:1

2

3

Page 35: Traducteur de byte code Java en byte code .Net

Autres algorithmes Pas de temps pour tous les voir:

instructions de création d’objets Java: 2 phases: new et appel méthode initialisation .Net : l’instruction newobj initialise l’objet en une étape

instructions d’appel de méthodes invoke* peuvent se traduire différemment selon le contexte

instructions d’accès au champs sémantique différente entre les deux plates-formes

instructions de branchement la traduction dépend de si l’on se trouve dans une exception

ou non

instructions de manipulation de la pile Java possède beaucoup plus d’instructions que .Net

Page 36: Traducteur de byte code Java en byte code .Net

Les exceptions de la machine virtuelle Que se passe-t-il lors d’une division par

zéro ?Java: lance java.lang.ArithmeticException .Net: lance System.DivideByZeroException

Une simple traduction du bloc catch ne va pas intercepter l’exception .Net

Algorithme: utiliser les blocs « filter » de .Net pour reconstruire une exception Java

Page 37: Traducteur de byte code Java en byte code .Net

Scénario 1

Java .Net

lecture bc. Java

Ø

écriture bc. .Net

System.Reflection.Emit

Désavantage: il faut implémenter une librairie de lecture de bytecode Java

Avantage: System.Reflection.Emit permet accès informations des classes .Net

Page 38: Traducteur de byte code Java en byte code .Net

Scénario 2Java .Net

lecture bt. Java

BCEL

écriture bt. .Net

Msil

Désavantage: ■ pas d’accès aux informations des classes .Net,

■ Msil non mature

Avantage: pas de librairie à implémenter à partir de rien

Assembleur bytecode .Net