Semantica Operazionale di un frammento di Java le

  • Slides: 63
Download presentation
Semantica Operazionale di un frammento di Java: le regole di transizione estensione (con piccole

Semantica Operazionale di un frammento di Java: le regole di transizione estensione (con piccole varianti) di quella in FONDAMENTI DI PROGRAMMAZIONE 1

Regole di transizione 4 regole che ci dicono come viene modificato uno stato per

Regole di transizione 4 regole che ci dicono come viene modificato uno stato per effetto dell’esecuzione di un certo costrutto del linguaggio 4 diverse relazioni di transizione, in corrispondenza dei diversi tipi di costrutti del linguaggio – espressioni, comandi, dichiarazioni di variabile, dichiarazioni di metodi, dichiarazioni di classe, ecc. 2

Regole di transizione 4 Non daremo una definizione completa, ma ci limiteremo alle caratteristiche

Regole di transizione 4 Non daremo una definizione completa, ma ci limiteremo alle caratteristiche nuove 4 Per esempio nei comandi trascuriamo composizione sequenziale, iterazione, condizionale, blocchi etc. 3

Dichiarazione di classe Class_decl : = class Id extends Id { Static_var_decl_list Static_meth_decl_list Inst_var_decl_list

Dichiarazione di classe Class_decl : = class Id extends Id { Static_var_decl_list Static_meth_decl_list Inst_var_decl_list Inst_meth_decl_list Costruttore } 4 assunzioni – c’è sempre extends • ogni classe estende la classe Object – le dichiarazioni di variabili e metodi statici sono “raggruppate” – esiste sempre il costruttore 4

Inizializzazioni 4 Java permette di inizializzare (al valore di una espressione) sia le variabili

Inizializzazioni 4 Java permette di inizializzare (al valore di una espressione) sia le variabili statiche quelle di istanza in una dichiarazione – le inizializzazioni delle variabili statiche vengono effettuate la prima volta che si usa una classe – le inizializzazioni delle variabili di istanza vengono effettuate all’atto della creazione di una istanza – in tutti e due i casi, l’inizializzazione può riguardare anche le superclassi 4 per semplicità, decidiamo di non avere inizializzazioni nelle dichiarazioni di variabile all’interno di classi 4 per questo ci aspettiamo che esista sempre un costruttore – eseguito quando si crea un’istanza 5

Dichiarazione di classe Ambiente delle classi: Cenv = Id -> Cdescr = Id *

Dichiarazione di classe Ambiente delle classi: Cenv = Id -> Cdescr = Id * Frame * Menv * Frame* Menv 4 la relazione di transizione Class_decl * Cenv cdecl Cenv L’ambiente delle classi viene esteso con la descrizione della nuova classe 6

Ricordiamo che 4 se c 1 è una sottoclasse (estende) c 2 – variabili

Ricordiamo che 4 se c 1 è una sottoclasse (estende) c 2 – variabili e metodi statici di c 2 (e delle superclassi) sono visibili direttamente da c 1 – variabili e metodi di istanza di c 2 (e delle superclassi) diventano anche variabili e metodi di istanza di c 1 (a meno di overriding (metodi riscritti)) 4 Come lo implementiamo? 4 Supponiamo di dover valutare la dichiarazione di c 1 (c 2 c’e’ gia’) 7

Variabili e metodi statici 4 Il frame delle variabili statiche e l’ambiente dei metodi

Variabili e metodi statici 4 Il frame delle variabili statiche e l’ambiente dei metodi statici della sottoclasse viene costruito valutando le relative dichiarazioni della sottoclasse 4 Quelli della superclasse sono comunque visibili tramite il puntatore alla superclasse 4 Di conseguenza variabili e metodi statici della superclasse sono condivisi tra gli oggetti della classe e della superclasse 8

Variabili e metodi d’istanza 4 il frame delle variabili di istanza per la sottoclasse

Variabili e metodi d’istanza 4 il frame delle variabili di istanza per la sottoclasse viene costruito a partire da quello della superclasse – estendendolo con le dichiarazioni delle variabili d’istanza della sottoclasse 4 l’ambiente dei metodi di istanza viene costruito a partire da quello della superclasse – estendendolo con le dichiarazioni dei metodi d’istanza della sottoclasse (realizza overriding) 9

Di conseguenza 4 ricordiamo che il frame delle variabili d’istanza e l’ambiente dei metodi

Di conseguenza 4 ricordiamo che il frame delle variabili d’istanza e l’ambiente dei metodi d’istanza nella descrizione della classe verranno utilizzati per creare gli oggetti, istanze della classe 4 quando verra’ creato un oggetto della sottoclasse c 1 copieremo nello heap il frame delle variabili d’istanza della classe c 1 (contiene gia’ le variabili di c 1 e quelle ereditate) 4 analogo per i metodi d’istanza e costruttori 10

Dichiarazione di classe r(b) = (_, _, _, j, m) m(b) = (_, c

Dichiarazione di classe r(b) = (_, _, _, j, m) m(b) = (_, c 1, _) <svdl, newframe()> vdecl j 1 <ivdl, copy(j)> vdecl j 2 <smdl, a, memptyenv()> mdecl m 1 <imdl, a, m> mdecl m 2 ________________________ <class a extends b {svdl smdl ivdl imdl c}, r> cdecl cbind(r, a, (b, j 1, m 1 , j 2, mbind(m 2, a, ([], c 1 c, a)))) 11

Osservazioni ü l’eventuale overriding è realizzato automaticamente dalle regole per la valutazione delle dichiarazioni

Osservazioni ü l’eventuale overriding è realizzato automaticamente dalle regole per la valutazione delle dichiarazioni dei metodi (tramite mbind) 4 il costruttore è aggiunto all’ambiente dei metodi d’istanza, componendo (sintatticamente) il corpo del costruttore della superclasse con quello della sottoclasse 12

Differenze dovute alla implementazione 4 il frame delle variabili di istanza viene costruito a

Differenze dovute alla implementazione 4 il frame delle variabili di istanza viene costruito a partire da una copia di quello della superclasse – i frames sono strutture modificabili, non possiamo condiverle – è necessario costruire la copia 4 l’ambiente dei metodi di istanza viene costruito a partire da quello della superclasse – Non sono modificabili, possiamo condividerle 13

Dichiarazioni di metodi Method_decl : = Id (Idlist) Blocco 4 guardiamo solo la dichiarazione

Dichiarazioni di metodi Method_decl : = Id (Idlist) Blocco 4 guardiamo solo la dichiarazione singola – per una lista di dichiarazioni, si ripete a partire dal risultato precedente Menv = Id -> Mdescr = Idlist * Blocco * ( Loc | Id ) Nella descrizione abbiamo il puntatore alla classe o 14 all’oggetto (che serve per l’esecuzione)

Dichiarazioni di metodi 4 la relazione di transizione Method_decl * Id * Menv mdecl

Dichiarazioni di metodi 4 la relazione di transizione Method_decl * Id * Menv mdecl Menv § Id e’ il puntatore alla classe o all’oggetto § Al momento della dichiarazione della classe e’ per tutti il puntatore alla classe (vedi la regola della dichiarazione di classe) § Per i metodi d’istanza verra’ modificato al momento della creazione degli oggetti (? ) 15

Dichiarazione di metodo Menv = Id -> Mdescr = Idlist * Blocco * (

Dichiarazione di metodo Menv = Id -> Mdescr = Idlist * Blocco * ( Loc | Id ) Method_decl * Id * Menv mdecl Menv <m (idlist) blocco, c, m> mdecl mbind(m, m, (idlist, blocco, c)) 4 l’eventuale overriding è realizzato automaticamente da mbind se esiste gia’ una associazione per m la sovrascrive con la nuova 16

Dichiarazioni di variabili Var_decl : = Type Id; 4 come già osservato, le dichiarazioni

Dichiarazioni di variabili Var_decl : = Type Id; 4 come già osservato, le dichiarazioni non hanno inizializzazione 4 guardiamo solo la dichiarazione singola – per una lista di dichiarazioni, si ripete a partire dal risultato precedente Frame = Id -> Val = (Bool | Int | Loc) 4 la relazione di transizione Var_decl * Frame vdecl Frame 17

Dichiarazione di variabile Frame = Id -> Val = (Bool | Int | Loc)

Dichiarazione di variabile Frame = Id -> Val = (Bool | Int | Loc) Var_decl * Frame vdecl Frame <t id; , j> vdecl bind(j, id, default(t)) 4 Estende j con la nuova associazione tra id ed il valore di default 4 la funzione default genera un valore di tipo t – 0 se t è intero – null se t è il tipo di un oggetto ü Notate che bind richiede che id non sia definito in j (non sono ammesse due dichiarazioni della stessa variabile in una lista) 18

Espressioni 4 dato che non abbiamo previsto inizializzazioni per le variabili (statiche e di

Espressioni 4 dato che non abbiamo previsto inizializzazioni per le variabili (statiche e di istanza) all’interno delle classi, le espressioni possono comparire solo all’interno dei metodi 4 consideriamo solo alcuni dei casi di espressioni – quelli che riguardano oggetti – trascuriamo i valori numerici, booleani (sotrattano in modo standard) 19

Espressioni Expr : = new Id | (creazione di istanza) Path Id (accesso al

Espressioni Expr : = new Id | (creazione di istanza) Path Id (accesso al valore di una variabile) Path : = Id. Objpath | (si parte dalla classe Id) this. Objpath | (si parte dall’oggetto corrente) Objpath : = | (cammino vuoto) Id. Objpath (si parte dall’oggetto Id) 4 ambigua, ma. . 20

La relazione di transizione per le espressioni Expr : = new Id | (creazione

La relazione di transizione per le espressioni Expr : = new Id | (creazione di istanza) Path Id (accesso al valore di una variabile) Expr * Cenv * Heap * Astack expr Val * Heap * Cenv § La creazione di oggetti modifica lo heap § L’esecuzione del costruttore puo’ modificare le variabili statiche (ambiente delle classi) 21

Idea: per creare un oggetto 4 creo una locazione nuova nello heap 4 nella

Idea: per creare un oggetto 4 creo una locazione nuova nello heap 4 nella descrizione dell’oggetto metto – il nome della classe – una copia del frame delle variabili di istanza (dalla classe) – una specializzazione sull’oggetto dell’ambiente di metodi di istanza (dalla classe) 4 Valuto il costruttore come un metodo d’istanza sull’oggetto 22

Creazione di oggetti r(a) = (_, _, _, j, m) l = newloc(z) m’

Creazione di oggetti r(a) = (_, _, _, j, m) l = newloc(z) m’ = instantiate(m, l) j’ = copy(j) z’’ = hbind(z, l, (a, j’, m’)) m’(a) = (_, b, _) s’= push(s, (l, push(emptystack(), newframe()))) <b, r, z’’, s’> com <z’’’, s’’, r’ > pop(s’’) ________________________ <new a, r, z, s> expr<l, z’’’ , r’ > 23

Expr : = Path Id (accesso al valore di una variabile) Le regole per

Expr : = Path Id (accesso al valore di una variabile) Le regole per l’accesso al valore di una variabile sono complicate, la ricerca dipende da §il metodo correntemente in esecuzione §La classe a cui appartiene il metodo (se statico) §L’oggetto a cui appartiene il metodo (se d’istanza) §Dal significato di Path 24

Per valutare Path Id q. Dobbiamo valutare Path a partire dal metodo corrente (met).

Per valutare Path Id q. Dobbiamo valutare Path a partire dal metodo corrente (met). Puo’ indicare § Ide (una classe) • Loc (un oggetto) • metodo corrente (se il path e’ vuoto) indicato da met q. Dobbiamo cercare il valore di Id a partire dal (Ide|Loc|met) indicato dal path 25

Come trovare il valore di un nome qualificato Expr : = Path Id Expr

Come trovare il valore di un nome qualificato Expr : = Path Id Expr * Cenv * Heap * Astack expr Val * Heap * Cenv <p, met, r, z , s > path o <a, o, r, z , s > naming v __________________________ <p a, r, z , s > expr<v, z , r > 4 i controlli statici garantiscono che il nome (nel frame opportuno) abbia già ricevuto un valore (inizializzazione o assegnamento) prima dell’uso 26

Risoluzione di nomi (semplici) 4 il riferimento ad un identificatore può in generale essere

Risoluzione di nomi (semplici) 4 il riferimento ad un identificatore può in generale essere risolto – nella pila di frames sulla testa dello stack delle attivazioni – nei frames delle variabili di istanza di un oggetto – nei frames di variabili statiche di una classe 4 il modo di effettuare la ricerca dipende da dove essa inizia – un metodo (quello correntemente attivo) – un oggetto – una classe Ide * (Ide | Loc | met) * Cenv * Heap * Astack naming Val 27

Dalla classe: nell’ordine 4 Variabili statiche (ambiente delle clasii) 4 Altrimenti si passa alla

Dalla classe: nell’ordine 4 Variabili statiche (ambiente delle clasii) 4 Altrimenti si passa alla superclasse tramite il puntatore 28

Dalla Classe Ide * (Ide | Loc | met) * Cenv * Heap *

Dalla Classe Ide * (Ide | Loc | met) * Cenv * Heap * Astack naming Val r(c) = (c 1, j, _, _, _) defined(j, i) _______________________ <i, c: Ide, r, z , s > naming j(i) r(c) = (c 1, j, _, _, _) not defined(j, i) <i, c 1, r, z , s > naming v _______________________ <i, c: Ide, r, z , s > naming v 29

Da un oggetto 4 Variabili d’istanza (nella descrizione dell’oggetto nella heap) 4 Altrimenti si

Da un oggetto 4 Variabili d’istanza (nella descrizione dell’oggetto nella heap) 4 Altrimenti si passa alla classe tramite il puntatatore (di conseguenza alle variabili statiche sue e delle superclassi) 30

Da un oggetto Ide * (Ide | Loc | met) * Cenv * Heap

Da un oggetto Ide * (Ide | Loc | met) * Cenv * Heap * Astack naming Val z(l) = (c, j, _) defined(j, i) _______________________ <i, l: Loc, r, z , s > naming j(i) z(l) = (c, j, _) not defined(j, i) <i, c, r, z , s > naming v _______________________ <i, l: Loc, r, z , s > naming v 31

Da un oggetto ü Stack locale (nel record d’attivazione al top della pila) ü

Da un oggetto ü Stack locale (nel record d’attivazione al top della pila) ü Altrimenti si passa alla classe o all’oggetto a cui il metodo appartiene tramite il puntatore nel record di attivazione 32

Dal metodo corrente: stack locale Ide * (Ide | Loc | met) * Cenv

Dal metodo corrente: stack locale Ide * (Ide | Loc | met) * Cenv * Heap * Astack naming Val top(s) = (x, t) j = top(t) defined(j, i) _______________________ <i, met, r, z , s > naming j(i) top(s) = (x, t) j = top(t) not defined(j, i) s’ = push(pop(s), (x, pop(t))) <i, met, r, z , s’> naming v _______________________ <i, met, r, z , s > naming v 33

Dal metodo corrente: passiamo alla classe o all’oggetto Ide * (Ide | Loc |

Dal metodo corrente: passiamo alla classe o all’oggetto Ide * (Ide | Loc | met) * Cenv * Heap * Astack naming Val top(s) = (x, t) empty(t) <i, x, r, z , s > naming v _______________________ <i, met, r, z , s > naming v 34

Qualificazione dei nomi (paths) Path : = Id. Objpath | this. Objpath | Objpath

Qualificazione dei nomi (paths) Path : = Id. Objpath | this. Objpath | Objpath : = | Id. Objpath 4 Un path puo’ indicare un oggetto (Loc), una classe (Ide), oppure puo’ essere vuoto 35

Qualificazione dei nomi (paths) 4 La semantica del path determina il punto di partenza

Qualificazione dei nomi (paths) 4 La semantica del path determina il punto di partenza della ricerca del nome 4 Per valutare un path a partire dal metodo corrente (met), una classe (Ide) o un oggetto (Loc) Path * (Ide | Loc | met) * Cenv * Heap * Astack path (Ide | Loc | met) 36

Path vuoto, this, identificatore classe Path * (Ide | Loc | met) * Cenv

Path vuoto, this, identificatore classe Path * (Ide | Loc | met) * Cenv * Heap * Astack path (Ide | Loc | met) < , x, r, z , s > path x top(s) = (l, _) ______________ <this, met, r, z , s > path l cdefined(r, c) ______________ <c, x, r, z , s > path c 37

Identificatore oggetto, composizione Path * (Ide | Loc | met) * Cenv * Heap

Identificatore oggetto, composizione Path * (Ide | Loc | met) * Cenv * Heap * Astack path (Ide | Loc | met) not cdefined(r, o) <o, x, r, z , s > naming o’ _____________________ <o, x, r, z , s > path o’ <p, x, r, z , s > path p’ <pl, p’, r, z , s > path o _________________________ <p. pl, x, r, z , s > path o 38

I comandi 4 un blocco (corpo di un metodo) è una sequenza di dichiarazioni

I comandi 4 un blocco (corpo di un metodo) è una sequenza di dichiarazioni e comandi (che possono anche essere blocchi nidificati) 4 la composizione sequenziale viene trattata in modo standard – nel costrutto c; cl valutiamo cl nello stato risultante dalla valutazione di c 4 trattiamo anche le dichiarazioni di variabili (locali al metodo) come comandi 4 vediamo solo alcuni casi di comandi – condizionali e loops hanno la semantica vista nel primo corso Com * Cenv * Heap * Astack com Heap * Astack * Cenv 39

Sintassi dei comandi Com : = {Com} | (blocco annidato) Path Ide = Expr

Sintassi dei comandi Com : = {Com} | (blocco annidato) Path Ide = Expr | (assegnamento) Type Ide = Expr | (dichiarazione con inizializzazione) Path Id (Expr_list) | (invocazione di metodo) Com * Cenv * Heap * Astack com Heap * Astack * Cenv 40

Semantica dei blocchi Com : = {Com} | (blocco annidato) 4 Per modellare i

Semantica dei blocchi Com : = {Com} | (blocco annidato) 4 Per modellare i blocchi si usa la pila dei frames nel record di attivazione 4 Ricordiamo che ogni record di attivazione ha la propria pila di frames che modella i blocchi locali 4 mettiamo un nuovo frame per il blocco da valutare (inizialmente vuoto) 4 Se una variabile appare in vari frames nella pila, si vede l’associazione piu’ recente 41

Semantica dei blocchi Com : = {Com} top(s) = (x, t) (blocco annidato) s’=push(pop(s),

Semantica dei blocchi Com : = {Com} top(s) = (x, t) (blocco annidato) s’=push(pop(s), (x, push(t , newframe()))) <c, r, z, s’> com <z’, s’’, r’ > top(s’’) = (x, t’) ________________________ <{c}, r, z, s> com <z’, push(pop(s’’), (x, pop(t’))), r’ > Valutiamo il comando c dopo avere aggiunto un frame nuovo al top della pila dei frames locali nel record di attivazione correntemente in esecuzione (x, t) 42

Semantica delle dichiarazioni Com : = Type Ide = Expr top(s) = (x, t)

Semantica delle dichiarazioni Com : = Type Ide = Expr top(s) = (x, t) (dichiarazione) j = top(t ) <e, r, z, s> expr <v, z’, r’ > j’= bind(j , i, v) s’=push(pop(s), (x, push(pop(t ) , j’))) _____________________ <t i = e, r, z, s> com <z’ , s’, r’ > 4 la bind “modifica” j, che e’ al top della pila dei frames nel record di attivazione corrente (x, t) 43

Semantica dell’assegnamento 1 Com : = Path Ide = Expr (assegnamento) 4 l’identificatore per

Semantica dell’assegnamento 1 Com : = Path Ide = Expr (assegnamento) 4 l’identificatore per cui va modificata l’associazione in un frame (a parte la qualificazione) può in generale essere – nella pila di frames sulla testa dello stack delle attivazioni – nei frames delle variabili di istanza di un oggetto – nei frames di variabili statiche di una classe 4 il modo di effettuare la ricerca dipende da dove essa inizia – un metodo (quello correntemente attivo) – un oggetto – una classe 4 simile al naming (invece di riportare il valore lo modifica Ide * (Ide | Loc | met) * Cenv * Heap * Astack update Heap * Astack * Cenv 44

Semantica dell’assegnamento 2 Com : = Path Ide = Expr (assegnamento) Com * Cenv

Semantica dell’assegnamento 2 Com : = Path Ide = Expr (assegnamento) Com * Cenv * Heap * Astack com Heap * Astack * Cenv <p, met, r, z , s > path c <e, r, z, s> expr <v, z’’, r’ > <i, v, c, r’, z’’, s> update<z’, s’ , r’ ’> _______________ <p i = e, r, z, s> com <z’, s’ , r’ ’ > Ide * Val * (Ide | Loc | met) * Cenv * Heap * Astack update Heap * Astack * Cenv 45

Update: da una classe Ide * Val * (Ide | Loc | met) *

Update: da una classe Ide * Val * (Ide | Loc | met) * Cenv * Heap * Astack update Heap * Astack * Cenv r(c) = (c 1, j 1, m 1 , j 2, m 2) defined(j 1, i) j’= update (j 1, i, v) r’= cbind (r, c, (c 1, j’, m 1 , j 2, m 2) ) _______________________ <i, v, c: Ide, r, z , s > update <z , s, r’ > r(c) = (c 1, j, _, _, _) not defined(j, i) <i, v, c 1, r, z , s > update <z’ , s’, r’ > _______________________ <i, v, c: Ide, r, z , s > update <z’ , s’, r’ > 46

Update: da un oggetto Ide * Val * (Ide | Loc | met) *

Update: da un oggetto Ide * Val * (Ide | Loc | met) * Cenv * Heap * Astack update Heap * Astack * Cenv z(l) = (c, j, m) defined(j, i) z’ = hbind(z , l, (c, update(j, i, v) , m)) _______________________________ <i, v, l: Loc, r, z , s > update < z’ , s, r > z(l) = (c, j, _) not defined(j, i) <i, v, c, r, z , s > update <z’ , s’, r’ > _______________________ <i, v, l: Loc, r, z , s > update <z’ , s’, r’ > 47

Update: dal metodo corrente Ide * Val * (Ide | Loc | met) *

Update: dal metodo corrente Ide * Val * (Ide | Loc | met) * Cenv * Heap * Astack update Heap * Astack * Cenv top(s) = (x, t) j = top(t) defined(j, i) s’ = push(pop(s), (x, push(pop(t) , update (j, i, v)))) _____________________________ <i, v, met, r, z , s > update <z , s’, r > top(s) = (x, t) j = top(t) not defined(j, i) s’ = push(pop(s), (x, pop(t))) <i, v, met, r, z , s’ > update <z’’, s’’, r’ > top(s’’) = (x, t’) s’’’ = push(pop(s’’), (x, push(t’, j))) _________________________________ <i, v, met, r, z, s > update <z’’, s’’’, r’> top(s) = (x, t) empty(t) <i, v, x, r, z , s > update <z’’, s’’, r’ > _________________________________ <i, v, met, r, z , s > update <z’’, s’’, r’ > 48

Invocazione di metodi Com : = Path Id (Expr_list) 4 un solo parametro 1.

Invocazione di metodi Com : = Path Id (Expr_list) 4 un solo parametro 1. Ricercare la descrizione del metodo associata Path Id (simile alla ricerca dei nomi di variabili) 2. Creare il record di attivazione da mettere al top della pila 3. Valutare il corpo del metodo 4. Rimuovere il record di attivazione 49

Ricerca dei metodi 4 Simile alla ricerca dei nomi di variabili 4 Unica differenza:

Ricerca dei metodi 4 Simile alla ricerca dei nomi di variabili 4 Unica differenza: non si cerca nello stack dei frames locali (non ci sono dichiarazioni di metodi annidate) 4 I metodi stanno nelle classi (se statici) o negli oggetti (se d’istanza) 4 La ricerca inizia da (Ide | Loc|met), risultato dalla valutazione del path Ide * (Ide | Loc|met) * Heap * Astack * Cenv fmet MDescr 50

Ricerca dei metodi: da una classe r(c) = (c 1, _, m, _, _)

Ricerca dei metodi: da una classe r(c) = (c 1, _, m, _, _) mdefined(m, f) _______________________ <f, c: Ide, r, z , s > fmet m(f) r(c) = (c 1, _, m, _, _) not mdefined(m, f) <f, c 1, r, z, s > fmet md _______________________ <f, c: Ide, r, z, s > fmet md 51

Ricerca dei metodi: da un oggetto z(l) = (c, _, m) mdefined(m, f) _______________________

Ricerca dei metodi: da un oggetto z(l) = (c, _, m) mdefined(m, f) _______________________ <f, l: Loc, r, z, s > fmet m(f) z(l) = (c, _, m) not mdefined(m, f) <f, c, r, z, s > fmet md _______________________ <f, l: Loc, r, z, s > fmet md 52

Ricerca dei metodi: dal metodo corrente top(s) = (x, _) <f, x, r, z

Ricerca dei metodi: dal metodo corrente top(s) = (x, _) <f, x, r, z s > fmet md _______________________ <f, met, r, z, s > fmet md Notate che saltiamo subito tramite il puntatore alla classe o all’oggetto! 53

Invocazione di metodi: commenti 4 4 4 dopo avere trovato la descrizione del metodo

Invocazione di metodi: commenti 4 4 4 dopo avere trovato la descrizione del metodo si valuta il parametro attuale si crea un nuovo stack di frames, il cui unico frame contiene l’associazione tra parametro formale e valore del parametro attuale si pusha sulla pila il record che contiene la classe o l’oggetto associato al metodo e la pila di frames si valuta il corpo del metodo Quando termina si elimina il record di attivazione 54

Invocazione di metodi Com : = Id (Expr) <p, met, r, z, s >

Invocazione di metodi Com : = Id (Expr) <p, met, r, z, s > path x <f, x, r, z, s > fmet (par, b, y) <e, r, z, s> expr <v, z’, r’ > j = bind(newframe(), par, v) s’ = push(s, (y, push(emptystack(), j))) <b, r’, z’, s’> com <z’’, s’’, r’ ’ > ________________________ <p f(e), r, z, s)> com <z’’, pop(s’’), r’ ’ > 55

Il naming 4 naming – tutti gli usi di nomi all’interno dei metodi (inclusi

Il naming 4 naming – tutti gli usi di nomi all’interno dei metodi (inclusi quelli usati nei paths) • variabili locali, variabili di istanza, variabili statiche, metodi di istanza, metodi statici sono staticamente controllati per verificarne l’esistenza in accordo con le regole di visibilità • quelle che abbiamo “implementato” nei vari meccanismi di naming 4 le regole di visibilità tengono anche conto degli attributi private, public, protected 4 il meccanismo dei packages (con esportazioni ed importazioni) – serve per raggruppare insiemi di classi introduce ulteriori restrizioni 56

I tipi 4 ogni entità (variabile, metodo) ha un tipo determinato staticamente – type

I tipi 4 ogni entità (variabile, metodo) ha un tipo determinato staticamente – type checking statico 4 nell’assegnamento e nel passaggio di parametri il tipo del valore è garantito solo essere un sottotipo di quello della variabile 4 per le variabili che denotano oggetti, ci può essere una differenza tra – il tipo apparente = quello della dichiarazione della variabile o del parametro formale – il tipo effettivo a run-time = quello costruito valutando l’espressione in un assegnamento o il parametro attuale – il type checking statico può solo tener conto del tipo apparente – la differenza tra tipo apparente e tipo effettivo per gli oggetti si riflette anche sulla verifica dei nomi, che devono essere visibili secondo il tipo apparente 57

Altre osservazioni generali 4 l’esecuzione inizia con l’invocazione del metodo (statico) main presente nell’ultima

Altre osservazioni generali 4 l’esecuzione inizia con l’invocazione del metodo (statico) main presente nell’ultima dichiarazione di classe 4 astrazioni sui dati utili (come le stringhe e gli arrays) sono definite da classi “primitive” 4 modificabilità delle strutture dati e condivisione (sharing) – gli oggetti di una classe possono essere • modificabili, se hanno delle operazioni che li modificano (per esempio, gli arrays) • non modificabili (per esempio, le stringhe) – un oggetto è condiviso da due entità se può essere raggiunto da entrambi • se è modificabile, le modifiche si riflettono su tutte le entità che lo “contengono” 4 effetti laterali (all’esterno) in un metodo – attraverso i parametri può solo modificare valori di tipo oggetto – può modificare variabili di istanza e variabili (statiche) di classe che vede 58

Il garbage collector 4 la gestione dinamica della heap è garantita dalla presenza di

Il garbage collector 4 la gestione dinamica della heap è garantita dalla presenza di un garbage collector nella JVM – quando la heap è piena e non sarebbe più possibile creare dinamicamente nuovi oggetti, il garbage collector riconosce tutti gli oggetti che non sono più raggiungibili a partire dalla pila e dall’ambiente delle classi e li “raccoglie”, rendendo disponibile la memoria relativa 4 è forse la principale causa del successo di Java rispetto ad altri linguaggi orientati ad oggetti (C++) – dove la restituzione degli oggetti “inutili” è a carico del programmatore, con gravi rischi nel caso di oggetti condivisi 4 prima di Java, il garbage collector era presente quasi esclusivamente in linguaggi funzionali (LISP, ML) e logici (PROLOG) – in cui le strutture allocate sulla heap sono molto più semplici e regolari 59

Java e affidabilità 4 la affidabilità – intesa come protezione da errori a tempo

Java e affidabilità 4 la affidabilità – intesa come protezione da errori a tempo di esecuzione è garantita al meglio in Java da vari meccanismi 4 il controllo dei nomi statico – a run time non è possibile tentare di accedere un nome non definito 4 il controllo dei tipi statico – a run time non si possono verificare errori di tipo (ma. . . ) 4 la presenza del garbage collector – non è possibile tentare di accedere oggetti non più presenti nella heap 4 la presenza di controlli a tempo di esecuzione, con sollevamento di eccezioni – controllo sugli indici per gli arrays – accesso a puntatori ad oggetti vuoti (null) – conversioni forzate di tipo (casting) 60

Risoluzione dei nomi nella compilazione 4 il compilatore Java – anche per fare il

Risoluzione dei nomi nella compilazione 4 il compilatore Java – anche per fare il controllo dei nomi 4 costruisce staticamente delle tabelle che corrispondono ai frames (della pila, delle variabili di istanza, delle variabili statiche), agli ambienti dei metodi (statici e di istanza) ed all’ambiente delle classi la posizione di un nome (di variabile, di metodo o di classe) all’interno di queste tabelle è decisa una volta per tutte a tempo di compilazione – i nomi possono tutti scomparire dalle tabelle, che diventano vettori di valori, descrizioni di classe o descrizioni di metodi – i riferimenti ai nomi (tipicamente nel codice dei metodi) possono essere rimpiazzati da “displacements” (posizioni) in una opportuna tabella 4 una ulteriore semplificazione è possibile per i metodi, dato che, a differenza dei valori delle variabili nei frames, essi non possono essere modificati – il riferimento al nome può essere direttamente rimpiazzato dal puntatore al codice e la tabella può essere eliminata 4 questo non è possibile per i metodi di istanza, a causa della possibile differenza tra tipo apparente e tipo effettivo (dispatching) 61

Come diventa lo stato (1) puntatore ad oggetto codice blocco f 1 codice blocco

Come diventa lo stato (1) puntatore ad oggetto codice blocco f 1 codice blocco f 2 codice blocco f 3 C A 2 a 23 f 1 (y, z) C b c 5 f 2 (w) C d ? e ? f 3 () f 4 (x) ? ? C () ? codice blocco f 4 codice blocco C B A Object 4 parte statica (classi) 62

Come diventa lo stato (2) x d 3 e C 4 f 3 ()

Come diventa lo stato (2) x d 3 e C 4 f 3 () f 4 (x) C () stack heap puntatori al codice dei metodi 4 parte dinamica (pila e heap) – è in esecuzione il metodo f 4 di una istanza di C 63