La struttura dello StackIl funzionamento della Macchina Astratta è basato sul suo Stack, poiché esso è coinvolto nell'interpretazione di ogni bytecode del programma; ciò perchè è tramite lo Stack Manager e quindi lo Stack, che l'interprete ha accesso a parte delle informazioni sullo stato corrente della macchina. I singoli elementi dello Stack, che vengono creati dallo Stack Manager e quindi inseriti e rimossi dallo Stack, sono detti Stack Frame. In figura è schematizzata la struttura dello Stack, di cui si evidenzia uno Stack Frame.
I vari Stack Frame vengono creati al momento dell'invocazione di
un metodo, e restano sullo Stack finché l'esecuzione dei
relativi bytecode non è terminata, in seguito ad un'istruzione
Return. In ogni istante la porzione di Stack al di sopra di
un dato Frame mantiene le informazioni associate alle invocazioni di
metodi generate, direttamente o indirettamente, dal metodo relativo
al Frame in questione. Quando questi metodi avranno terminato la
loro esecuzione e restituito i loro risultati, sarà necessario
ripristinare lo stato dell'interprete al momento della prima invocazione. Il puntatore chiamato Sender fa riferimento all'Environment dello Stack Frame del metodo che ha invocato l'esecuzione del metodo corrente. Tale riferimento sarà necessario per consentire allo Stack Manager di ritrovare le informazioni contenute nell'Environment del Frame precedente.
Si osservi che delle tre aree che costituiscono la struttura dello
Stack Frame, due hanno lunghezza variabile, diversa da metodo a
metodo, e precisamente la prima o area delle variabili locali e
l'ultima o stack degli operandi. L'area delle variabili contiene il riferimento all'oggetto ( this ) su cui si sta eseguendo il metodo ( nel caso di metodi istanza ), nonché gli argomenti passati al metodo corrente e le sue variabili locali. Il metodo corrente può manipolare il valore di queste variabili solo tramite lo stack degli operandi, caricandovi il loro valore o prelevando dal top i nuovi risultati. Tale meccanismo è usato per tutte le operazioni su numeri e oggetti; è per questo motivo che sono presenti, nell'Instruction Set, due categorie di istruzioni correlate allo stack degli operandi: le PUSH, che consentono di caricare i valori da varie parti della macchina sul top dello stack, e di converso le POP, che memorizzano il valore che si trova sul top dello stack in varie aree di memoria.
Ma lo stack degli operandi ha anche un'altro uso, che spiega un po'
il motivo per cui ogni Stack Frame ha l'organizzazione
mostrata in figura: esso viene utilizzato per passare gli argomenti ai
metodi.
Ma come fa lo Stack Manager a sapere di quanto deve "scendere"
nello stack degli operandi per prendere tutti gli argomenti del nuovo
metodo? Questa informazione viene ricavata dagli operandi del
bytecode, che costituiscono un indice a 16 bits in una
tabella ( la Run-Time Costant Pool ) all'interno della
struttura puntata dal campo Class Structure.
|