:: Enseignements :: Master :: M2 :: 2012-2013 :: Machine Virtuelle (et bazard autour ...) ::
[LOGO]

Object, allocation, accès aux champs, appel de méthode, GC


Le but de ce TD est de finir l'implantation de l'interpréteur à pile du TD précédent.
L'archive au format ZIP contenant une base de code (les classes de l'AST, le rewriter et le FullInterpreter) est diponible ici

Exercice 1 - Interpreteur

  1. Comment le FunctionRewriter fait la différence entre un appel de fonction et un appel de création d'un objet ?
    Par exemple dans la code ci-dessous, foo() est un appel de fonction et A() une création d'objet.
                classdef A { }
                
                def foo():
                  2
                  
                def main():
                  foo()
                  A()
                    
              
  2. Ecrire dans l'interpreteur le code permettant l'allocation d'un objet et tester avec le code suivant:
               classdef Point { x, y }
                
               def main():
                  p = Point(1, 2)
                  print(p)
             
  3. Implanter dans l'interpreteur l'opérateur '~' qui test la classe d'un objet.
              classdef A { }
              classdef B { } 
              
              def main(): 
                o = A()
                o2 = B()
                print(o ~ A, " ", o ~ B)
                print(o2 ~ A, " ", o2 ~ B)
             
  4. Ecrire dans l'interpreteur le code permettant l'accès aux valeurs des champs
              classdef Point { x, y }
              
              def main(): 
                p = Point(1, 2)
                print(p.x)
             

Exercice 2 - Garbage collector

On souhaite implanter un garbage collector Mark & Compact in-place.

  1. Quand doit-on exécuter l'algorithme de garbage collector ?
  2. Ecrire le code permettant le parcours des références sur la pile.
  3. Modifier le code pour marquer tous les objets vivants récursivement.
    Avec quelle valeur doit-on marquer les objets ? (lire l'ensemble des questions de l'exercice avant de répondre)
    Pourquoi les objets représentant true, false et undefined sont spéciaux ?
  4. Ecrire le code de parcours du heap affichant si les objets sont mort ou vivants.
  5. Modifier le code du parcours du heap pour calculer la nouvelle addresse des objets.
    Pourquoi les références stockées dans les champs sont elles des réfèrences vers des objets qui ont déjà une nouvelle adresse ?
  6. Ajouter le code qui ré-écrit les réfèrences qu'il y a sur la pile et qui bouge les objets vivants à leur nouvelle place dans le heap.

Exercice 3 - Appel de méthode

On souhaite maintenant implanter l'association d'une fonction à une classe ainsi que l'appel de méthode.

  1. Dans un premier temps, on souhaite permettre que la création d'un objet envoie moins d'argument que le nombre de champs. Modifier le code de l'interpreteur pour que les champs non initialisées est la valeur undefined.
              classdef Point { x, y }
              
              def main(): 
                p = Point()
                print(p.x, " ", p.y)
             
  2. Implanter les opérations permettant de considérer une fonction comme une méthode et d'appeler une méthode.
               classdef Foo { x }
               
               def bar(foo):
                 print(foo.x)
               
               def main():
                 foo = Foo(42)
                 Foo.bar = bar
                 foo.bar()
             
  3. Implanter l'allocation d'objet lorsque les variables correspondant aux champs sont nommées
               classdef Point { x, y }
               
               def main():
                 p = Point { y = 23, x = 34 }
                 print(p)