Newsgroup: it.comp.java
Titolo: Java bytecode

ciao a tutti,
secondo voi, il java bytecode č fortemente tipato come il java o no?
Grazie per le vostre risposte
simone

 secondo voi, il java bytecode è fortemente tipato come il java o no?
Cosa significa "secondo noi"? Non e' una questione di opinione, basta
andarsi a leggere le specifiche.
...inoltre e' un po' difficile confrontare un linguaggio di alto livello
come Java, con uno di basso livello come il Java bytecode (confrontabile
con un linguaggio macchina).
-- 
Lucio Benfante
Java User Group Padova: 
http://www.jugpadova.it
Brainbench MVP for Java 1: 
http://www.brainbench.com
MyTranscript: 
http://www.brainbench.com/transcript.jsp?pid=167064

 andarsi a leggere le specifiche.
dimenticavo il riferimento alle specifiche:
http://java.sun.com/docs/books/vmspec/2nd-edition/html/VMSpecTOC.doc.html


 simone
É il bytecode ad essere eseguito, non il sorgente. Non avrebbe senso perdere
le informazioni sul tipo delle variabili in fase di compilazione.
Questo dubbio potrebbe venirti dall'aver dato un'occhiata a qualche sorgente
un po' più avanzato rispetto ad un tutorial... con altissime probabilità di
vedere assegnato un oggetto creato con new ad un riferimento di classe
apparentemente diversa.
Non per polemizzare... ma forse non sarebbe meglio ripassassare i concetti
di ereditarietà e polimorfismo?
(tieni sempre conto che il bytecode è la traduzione diretta di un sorgente
.java, tanto che, decompilandolo, è possibile risalire al sorgente _quasi_
originale, compresi i tipi delle variabili...)
-- 
Fermiamo Scientology prima che sia troppo tardi!!!
http://xenu.com-it.net
 - 
http://xenu.freewinds.cx/
(per rispondere personalmente leva IlDitoDalCulo)

 con un linguaggio macchina).
ho detto così perchè oggi ho letto una tesi di Jerome Miecznikowski su "New
algorithms for a Java decompiler and their implementation in Soot " e
nell'introduzione ci stava questa frase: "The Java Virtual Machine
Specification of valid bytecode is much less restrictive than the Java
Language Specification of valid Java source programs. For example, bytecode
has unstructured control flow, loose local typing, and few restrictions on
method modifiers. By contrast, the Java language has highly structured
control flow, strong local typing, and many restrictions on its method
modifiers". E' quel "loose local typing" che mi suona strano, o sbaglio?
Simone

 modifiers". E' quel "loose local typing" che mi suona strano, o sbaglio?
All'interno della JVM le variabili vengono memorizzate all'interno di 
registri. Uno stesso registro puň contenere valori di un tipo diverso in 
certi istanti dell'esecuzione. E' compito del verificatore accertarsi 
che per ad ogni singola indirizzo del programma il registro abbia sempre 
lo stesso tipo, indipendentemente dal flusso di esecuzione del metodo.
Esempio: il metodo "equals" di java.lang.Object, ottenuto facendo:
javap -c java.lang.Object
Method boolean equals(java.lang.Object)
    0 aload_0
    1 aload_1
    2 if_acmpne 9
    5 iconst_1
    6 goto 10
    9 iconst_0
   10 ireturn
I registri sono lo 0 e l'1 che contengono il "this" e l'unico parametro. 
Quindi i registri sono di tipo java.lang.Object ad ogni istruzione.
Questo esempio naturalmente č banale. Comunque nulla impedisce che il 
compilatore utilizzi un registro con un certo tipo (ad esempio 
java.lang.Object inizialmente) e poi dopo ad un altro (ad esempio int 
per le restanti istruzioni).
Ecco un esempio modificato, in cui faccio lo store del risultato nel 
registro 0 prima di restituirlo con ireturn (a destra metto il tipo dei 
registri):
Method boolean equals(java.lang.Object)
  0 aload_0          0: java.lang.Object, 1: java.lang.Object
  1 aload_1          0: java.lang.Object, 1: java.lang.Object
  2 if_acmpne 6      0: java.lang.Object, 1: java.lang.Object
  3 iconst_1         0: java.lang.Object, 1: java.lang.Object
  4 istore_0         0: java.lang.Object, 1: java.lang.Object
  5 goto 8           0: int             , 1: java.lang.Object
  6 iconst_0         0: java.lang.Object, 1: java.lang.Object
  7 istore 0         0: java.lang.Object, 1: java.lang.Object
  8 iload_0          0: int             , 1: java.lang.Object
  9 ireturn          0: int             , 1: java.lang.Object
Come vedi ad istruzioni 5, 8 e 9 il registro 0 adesso ha tipo int, il 
che consente poi di fare iload_0 ad istruzione 8 (carico sullo stack il 
contenuto del registro 0, di tipo int) e ireturn a riga 9 (restituisco 
il valore che ho sullo stack, sempre di tipo int naturalmente).
Se ti interessa un tool interessante per vedere queste cose ti consiglio 
BCEL:
http://jakarta.apache.org/bcel/
che al suo interno contiene JustIce, un verificatore di bytecode, ecco 
qui qualche screenshot:
http://bcel.sourceforge.net/justice/justice.html
Gaetano

 certi istanti dell'esecuzione. [...]
Queste cose naturalmente sono spiegate nella Java Virtual Machine 
Specification, come aveva già scritto Lucio Benfante:
http://java.sun.com/docs/books/vmspec/2nd-edition/html/VMSpecTOC.doc.html
Gaetano



Oltre a quello che ti ha gia' detto Gaetano, credo che quell'affermazione
faccia riferimento anche a questa frase delle specifiche (4.9.2 The
Bytecode Verifier): "For each instruction of the method, the verifier
records the contents of the operand stack and the contents of the local
variable array prior to the execution of that instruction. For the operand
stack, it needs to know the stack height and the type of each value on it.
For each local variable, it needs to know either the type of the contents
of that local variable or that the local variable contains an unusable or
unknown value (it might be uninitialized). The bytecode verifier does not
need to distinguish between the integral types (e.g., byte, short, char)
when determining the value types on the operand stack."
Quindi, mentre per l'operand stack e' necessario che il verifier conosca
il tipo, per la variabile locale e' sufficiente che sia in grado di
stabilire che il valore e' usabile. Inoltre anche sull'operand stack non
c'e' bisogno di distinguere fra i vari tipi integral.
Tutto cio', ad esempio, fa in modo che tipi diversi possano essere
mischiati senza nessuna conversione.
