2009-03-27 21 views
18

La mia classe di compilatori sta creando un linguaggio che intendiamo compilare in Bytecode Java. Abbiamo fatto molti progressi e stiamo avvicinando il momento in cui è il momento di generare codice.Compilare a bytecode java (senza utilizzare Java)

Stiamo riscontrando problemi nell'individuare informazioni su come creare file .class dal nostro compilatore. Avete delle risorse che possono darci un po 'di assistenza? Abbiamo già un sacco di documentazione sul set di istruzioni, ma abbiamo bisogno di informazioni su come compilare direttamente il file di classe/la scrittura di hex.

Non abbiamo bisogno di informazioni o suggerimenti sulla decompilazione dei file .class.

Anche un semplice esempio di scrittura di un file .class da zero sarebbe eccellente.

Le specifiche JVM non sono ciò che cerchiamo. Quello di cui abbiamo veramente bisogno è un esempio o una soluzione.

+0

ho appena scritto un file di parser di classe ... le informazioni che è necessario emettere bytecode è contenuto nel capitolo 4. Qual è specificamente esso che si trova privo di capitolo 4? – TofuBeer

+0

Potresti darci un tutorial o un esempio? – Allyn

+0

Vedere il mio aggiornamento, ma penso che sia necessario essere più specifici su quale parte di emettere un file di classe che non si capisce. – TofuBeer

risposta

8

Le specifiche VM: The Class File Format e The Java Virtual Machine Instruction Set dovrebbero farlo.

È possibile consultare la libreria di ingegneria del codice Byte (BCEL) per l'ispirazione, nonché Findbugs (deve leggere/comprendere i file di classe).

+2

Suggerirei ASM piuttosto che BCEL per la tua sanità mentale. –

+0

non hanno usato nessuno di essi, l'ho appena suggerito come riferimento per vedere come è stato scritto il file di classe (dico ancora che i capitoli 4 e 6 sono tutto ciò che è necessario) a meno che non si presentino problemi specifici. – TofuBeer

2

Il JVM specification è probabilmente quello che stai cercando, in particolare chapter 4 - the class file format.

+2

Qualcun altro dà questa risposta e ottengono un voto negativo per raccomandare la specifica JVM nonostante la frase in grassetto - ma Jon ottiene tre voti positivi. Ha ragione, ma scommetto che qualcuno senza la credenza pazza che Jon ha accumulato viene dissuaso. Puntelli a te, Jon. – duffymo

+1

difficile da dire, sia la risposta di Jon sia la modifica si sono verificate "un'ora fa" ma la riga in grassetto sul non volere la specifica JVM è stata modificata, quindi la sua probabile risposta di Jon è avvenuta prima della modifica. – shsteimer

+0

Jon e I suggeriscono le specifiche della VM. La votazione si è conclusa e quindi la modifica o la modifica e il voto giù. In entrambi i casi, la modifica e il voto negativo sono avvenuti più o meno allo stesso tempo. – TofuBeer

9

Esistono numerosi progetti che forniscono un'interfaccia di alto livello per la creazione di file di classe Java senza dover scrivere da soli i file di classe. Date un'occhiata al seguente:

Tutti offrono un'API per creare file di classe. Puoi sempre guardare il codice che hanno scritto per fare questo e scrivere un codice simile per il tuo compilatore, anche se immagino che sia una buona dose di lavoro.

Con BCEL dare un'occhiata a ClassGen, che dovrebbe consentire di scrivere file di classe nel formato desiderato, un semplice esempio segue:

ClassGen cg = new ClassGen("HelloWorld", "java.lang.Object", 
          "<generated>", ACC_PUBLIC | ACC_SUPER, 
          null); 
6

Mi dispiace deludervi, ma the VM specs sono esattamente quello che cerchi. Se non riesci a gestire le specifiche, forse non dovresti scrivere i compilatori, dopotutto.

4

Immagino che si possa provare a utilizzare gli strumenti esistenti ed esaminare l'effetto delle modifiche incrementali al codice byte risultante.

Fonte:

public class Hello { 
     public static void main(String[] args) { 
       System.out.println("H"); 
     } 
} 

javap uscita:

Compiled from "Hello.java" 
public class Hello extends java.lang.Object{ 
public Hello(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: return 

public static void main(java.lang.String[]); 
    Code: 
    0: getstatic  #2; //Field java/lang/System.out:Ljava/io/PrintStream; 
    3: ldc  #3; //String H 
    5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 
    8: return 

} 

binario:

CA FE BA BE 00 00 00 32 00 1D 0A 00 06 00 0F 09   _______2________ 
00 10 00 11 08 00 12 0A 00 13 00 14 07 00 15 07   ________________ 
00 16 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29   _____<init>___() 
56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E   V___Code___LineN 
75 6D 62 65 72 54 61 62 6C 65 01 00 04 6D 61 69   umberTable___mai 
6E 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67   n___([Ljava/lang 
2F 53 74 72 69 6E 67 3B 29 56 01 00 0A 53 6F 75   /String;)V___Sou 
72 63 65 46 69 6C 65 01 00 0A 48 65 6C 6C 6F 2E   rceFile___Hello. 
6A 61 76 61 0C 00 07 00 08 07 00 17 0C 00 18 00   java____________ 
19 01 00 01 48 07 00 1A 0C 00 1B 00 1C 01 00 05   ____H___________ 
48 65 6C 6C 6F 01 00 10 6A 61 76 61 2F 6C 61 6E   Hello___java/lan 
67 2F 4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F   g/Object___java/ 
6C 61 6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75   lang/System___ou 
74 01 00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69   t___Ljava/io/Pri 
6E 74 53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61   ntStream;___java 
2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01   /io/PrintStream_ 
00 07 70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61   __println___(Lja 
76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29   va/lang/String;) 
56 00 21 00 05 00 06 00 00 00 00 00 02 00 01 00   V_!_____________ 
07 00 08 00 01 00 09 00 00 00 1D 00 01 00 01 00   ________________ 
00 00 05 2A B7 00 01 B1 00 00 00 01 00 0A 00 00   ___*____________ 
00 06 00 01 00 00 00 01 00 09 00 0B 00 0C 00 01   ________________ 
00 09 00 00 00 25 00 02 00 01 00 00 00 09 B2 00   _____%__________ 
02 12 03 B6 00 04 B1 00 00 00 01 00 0A 00 00 00   ________________ 
0A 00 02 00 00 00 03 00 08 00 04 00 01 00 0D 00   ________________ 
00 00 02 00 0E           _____