\chapter*{Ringraziamenti} \addcontentsline{toc}{chapter}{Ringraziamenti} Desidero ringraziare il Prof. Massimo Ancona per avermi sostenuto e dato la possibilità di lavorare a questo progetto. Un ringraziamento particolare anche ai componenti del progetto \pypy: Armin e Samuele per aver sempre risposto con pazienza alle mie numerose domande; Carl Friedrich per la sua amicizia e ospitalità; Holger, Michael, i due Anders, Niklaus, Eric, Maciej, Christian e tutti gli altri per avermi accolto con entusiasmo e aiutato nel mio lavoro. Inoltre ringrazio la mia famiglia che mi ha sempre sostenuto e che soprattutto mi ha pazientemente sopportato quando ero nervoso ed irascibile negli ultimi mesi. E chiedo scusa al mio nipotino Nicolò per non aver avuto molto tempo da dedicargli. Desidero ringraziare anche i miei amici, che mi sono sempre stati vicini soprattutto nei momenti difficili: Elisa perché c'è da sempre; Danila perché c'è sempre; Daniela, Cristina, Annalisa e tutti gli altri che non posso citare per motivi di spazio, perché so di poter contare su di loro. Una menzione particolare per Fabrizio e Marco per avermi fatto conoscere i piaceri della Val d'Aosta e del \emph{genepy}. Infine ringrazio i miei compagni di università, che hanno l'indiscusso merito di avermi sopportato per cinque lunghi anni: Marco, con cui ho condiviso anche i cinque anni delle superiori; Andrea, sempre pronto a rispondere alle mie innumerevoli domande; un altro Marco (per gli amici \emph{John}), sempre pronto a pormi innumerevoli domande; Marianna, Deborah, Daniela, Francesco e tanti altri per avermi tenuto compagnia nelle mie pur non tanto frequenti giornate al DISI. \chapter*{Introduzione} \addcontentsline{toc}{chapter}{Introduzione} \textbf{Python} è un linguaggio di programmazione diventato molto popolare negli ultimi anni. Esso è un linguaggio multi-paradigma: questo significa che permette allo sviluppatore di adottare molteplici stili di programmazione, anziché forzarlo ad usarne uno in particolare. Esempi di paradigmi supportati sono quello orientato agli oggetti, programmazione strutturata, programmazione funzionale e aspect oriented programming. Python è \textbf{tipizzato dinamicamente} e utilizza un garbage collector per la gestione della memoria. Una importante caratteristica di Python è la risoluzione dinamica dei nomi, che consente di selezionare i metodi e le variabili da usare durante l'esecuzione del programma anziché durante la sua compilazione. A volte ci si riferisce a Python come ad un \textbf{linguaggio di scripting}. Nella pratica, esso è usato sia per lo sviluppo di applicazioni che per la stesura di script occasionali. Il linguaggio di programmazione in sé è specificato dal \emph{Python Reference Manual} \cite{python-ref}. Ci sono diverse implementazioni di queste specifiche: la più usata e diffusa è conosciuta come \emph{Classical Python} (CPython) e può essere considerata come l'implementazione di riferimento del linguaggio. Inoltre ci sono un paio di implementazioni alternative, ognuna con le proprie peculiarità: ad esempio possiamo citare \emph{Jython} \cite{jython}, che gira sulla \emph{Java Virtual Machine}, \emph{IronPython} \cite{ironpython}, che si integra nel \emph{.NET Framework} e \emph{Python for Series 60} \cite{python-s60}, che gira sui telefoni cellulari. Infine, il progetto \pypy \cite{pypy} ha lo scopo di scrivere una implementazione di Python in Python stesso. Lo scopo di questa tesi è di iniziare ad estendere \pypy\ in modo da ottenere un \textbf{interprete Python che gira all'interno del .NET Framework}. Non bisogna considerare questo progetto come un semplice clone di \emph{IronPython}: anche se i due progetti hanno qualche obiettivo in comune, gli sviluppi futuri di questo progetto potrebbero andare oltre \emph{IronPython}, perché esso può essere esteso e riutilizzato in diverse maniere, come vedremo nell'ultimo capitolo. \pagenumbering{arabic} \chapter{Abstract} \section{Una panoramica su \pypy} \pypy è un'implementazione del linguaggio di programmazione Python scritta in Python stesso. Gli scopi a lungo termine del progetto sono di produrre interpreti Python per un grosso numero di piattaforme diverse, grandi e piccole. \pypy è composto da due sottosistemi indipendenti: lo \emph{standard interpreter} e il \emph{translation process}; il primo implementa l'interprete Python vero e proprio ed è scritto in un sottoinseme di Python, chiamato RPython. Il secondo sottosistema accetta in input programmi scritti in RPython, quale ad esempio lo \emph{standard interpreter}, e produce degli eseguibili a basso livello più efficienti. Il processo di traduzione è suddiviso in quattro parti: \begin{itemize} \item Generazione dei diagrammi di flusso \item Annotazione dei tipi \item \emph{Rtyping} \item Generazione del codice \end{itemize} Il primo passo accetta in input un programma scritto in RPython e produce dei diagrammi di flusso che lo rappresentano e sono adatti ad essere manipolati dai passi successivi. Il passo di Annotazione esamina i diagrammi di flusso generati e, tramite il procedimento conosciuto come \emph{abstract interpretation}, assegna ad ogni variabile del programma il tipo di dato più generale che essa può assumere. Se ad esempio una variabile può contenere istanze di due classi diversi aventi una sopraclasse comune, l'annotazione corrisponderà proprio alla sopraclasse comune. Il passo di \emph{Rtyping} traduce i tipi ad alto livello annotati al passo precedente in tipi a basso livello in modo da facilitare il compito del passo successivo. Esistono due tipi di \emph{typesystem} che possono essere utilizzato: \begin{itemize} \item \emph{lltypesystem} è adatto per piattaforme a basso livello quale ad esempio il C: i tipi ad alto livello vengono espressi in termini di strutture e puntatori. Ad esempio, una lista di interi può essere tradotta in un array di \texttt{int}; \item \emph{ootypesystem} è adatto per piattaforme ad oggetti, quali ad esempio Java e .NET: i tipi ad alto livello vengono espressi in termini di classi e istanze. Ad esempio, una lista di interi può essere tradotta in una istanza di un'ipotetica classe di libreria \texttt{List}. \end{itemize} Infine, il passo di generazione del codice accetta in input i diagrammi di flusso specializzati dall'\emph{rtyper} e genera codice a basso livello adatto ad essere compilato ed eseguito. Esistono diversi \emph{backend} per questo scopo, uno per ogni piattaforma supportata da \pypy. Esempi di backend sono quello che genera codice C e quello che genera codice \emph{Javascript}. La figura \ref{fig:big-picture} mostra le relazioni che intercorrono tra i sottosistemi di \pypy. \begin{figure}[h] \centering \fbox{\scalebox{0.60}{\includegraphics{images/big-picture.png}}} \caption{\pypy\ subsystems} \label{fig:big-picture} \end{figure} Lo scopo della tesi è di produrre un backend che produce codice per la macchina virtuale \emph{CLI (Common Language Infrastructure)}, che è alla base della piattaforma .NET. \section{Panoramica su \emph{ootypesystem}} \emph{ootypesystem} è la parte dell'\emph{rtyper} che si occupa di specializzare i tipi ad alto livello in termini di tipi più a basso livello disponibili su una generica piattaforma ad oggetti. Esso è progettato per essere utilizzato da vari backend, anche molto diversi fra di loro, per cui deve tenere conto delle varie differenze che possono esistere tra le piattaforme di destinazione. \emph{ootypesystem} assume che la piattaforma di destinazione abbia supporto nativo per le classi e le istanze e che supporti l'ereditarietà singola. Le classi sono considerate oggetti del prim'ordine, per cui possono essere memorizzate in una variabile e passate ad una funzione. Inoltre esso è \emph{tipizzato staticamente}, e non supporta conversioni implicite da sottoclasse a superclasse. I backend che supportano l'\emph{upcasting} implicito possono semplicemente ignorare le relative istruzioni. Infine, si assume che la piattaforma di destinazione abbia supporto nativo per le più comuni strutture dati, quali liste e hashtable: esse sono usate per implementare le strutture dati di RPython. \section{Il backend CLI} \emph{gencli} è il backend che si occupa di generare codice per la piattaforma .NET. Esso è progettato in modo da funzionare sia con l'implementazione di Microsoft (\emph{CLR, Common Language Runtime}), che con Mono. Esso genera codice IL (\emph{Intermediate Language}) ed è composto da diversi moduli: \begin{itemize} \item Il \emph{typesystem}, che si occupa di tradurre i tipi generati da \emph{ootypesystem} in tipi disponibili sulla piattaforma .NET; \item un generatore di codice, che si occupa di tradurre i diagrammi di flusso in istruzioni IL; \item un generatore di classi, che si occupa di tradurre le classi RPython in classi .NET. \end{itemize} Siccome la piattaforma .NET è molto espressiva spesso il processo di traduzione è molto semplice da effettuare, perché esiste una relazione 1-a-1 tra le funzionalità di RPython e quelle della nostra macchina virtuale. Per semplificare il backend, alcune parti necesarie per garantire il corretto funzionamento dei programmi compilati sono state scritte in C\# e compilate in una libreria di supporto chiamata \emph{pypylib}. \section{Conclusioni e sviluppi futuri} Al momento della scrittura \emph{gencli} è un progetto abbastanza mature, sebbene non completo. Esso è in grado di compilare correttamente un grosso numero di spezzoni di codice usati per il testing e due programmi di benchmark di dimensioni medie. I due benchmark possono essere usati per fornire una prima analisi delle prestazioni del codice generato; la comparazione è fatta con il backend C con e senza ottimizzazioni. Il primo benchmark, \emph{pystone}, misura le prestazioni algoritmiche: \emph{gencli} è risultato circa 27 volte e 9 volte più lento del backend C con le ottimizzazioni attivate e disattivate, rispettivamente. Il secondo benchmark, \emph{richards}, misura le prestazioni dei costrutti object oriented: in questo caso \emph{gencli} è risultato circa 4 volte e 2 volte più lento del backend C con le ottimizzazioni attivate e disattivate, rispettivamente. Questa grossa differenza rispetto al precedente benchmark è presumibilmente attribuibile alla macchina virtuale sottostante, che probabilmente è ottimizzata per gestire proprio questi tipi di costrutti. Infine, il progetto è aperto a numerosi sviluppi futuri; tra essi citiamo la possibilità di ottimizzare il codice generato, l'integrazione dell'interprete Python con il .NET Framework e l'estensione di \emph{gencli} in modo da poter essere utlizzato come un vero e proprio compilatore da RPython a .NET.