2010-11-13 33 views
0

Dans mon interpréteur, je dois gérer ses objets d'exécution, ainsi que ses structures de données internes.Comment gérer la mémoire des structures de données et le tas d'une machine virtuelle en langage C

Je voudrais créer un interpréteur dans lequel il n'y a aucune différence entre les structures de données d'interpréteur (pile, table de symboles) et les objets créés par l'utilisateur. J'ai vu cela d'abord dans Little Smalltalk. De cette façon, l'interpréteur ressemble à une minuscule machine réelle, par rapport aux structures d'interpréteur vivant dans le tas géré et toutes étant du même type (comme l'architecture de von Neumann). Je pense que c'est la façon la plus cool et excitante d'écrire un interprète.

Mais je voudrais faire un peu différemment, en créant les objets gérés comme des structures C, et non des tableaux, comme normalement est fait. Le problème avec les structures C, se pose quand je voudrais essayer de recueillir ou de redimensionner le tas. Les pointeurs seraient invalidés.

Quelqu'un a-t-il pensé à faire cela avec des pointeurs? Je sais que c'est pratiquement impossible, mais quelqu'un est venu près?

+4

Je suis désolé. Je ne peux pas rassembler assez pour comprendre ce que vous demandez. –

+0

Je suis désolé encore plus! L'anglais n'est pas ma langue maternelle, parfois en écrivant en anglais je brouille ce que je pense à écrire. Obtient +1! –

+1

Vous ne pouvez pas utiliser standard 'malloc',' realloc', 'free' pour" programme tas "et" structures de données "? – pmg

Répondre

1

Doug Lea a écrit la base de certaines des implémentations de malloc là-bas, en 1994.

Vous pouvez télécharger le domaine public source:

http://g.oswego.edu/dl/html/malloc.html 
+0

Merci Jim, votre aide et de nos amis sont inestimables! +1 –

0

J'ai eu les mêmes préoccupations pour mon interprète Postscript. Une discussion here.

La façon dont j'ai contourné l'invalidation du pointeur est d'avoir deux couches d'adressage. Virtual adresses, si vous voulez.

La structure de données de base est allouée séparément et comporte des pointeurs vers l'adresse de base, la taille maximale allouée et la taille actuellement utilisée. A l'adresse zéro dans la mémoire se trouve la première table d'adresse qui contient les tailles d'allocation et les offsets de base (entiers, ou "curseurs", qui, ajoutés au pointeur de base, donnent un pointeur C aux données).

Depuis l'interprète est non-interruption, les fonctions de l'opérateur doivent pas se soucier des pointeurs deviennent invalides au cours de leur exécution, de sorte que les frais généraux d'aller chercher le pointeur de la poignée (une table-index, l'utilisateur réel pointeur), le besoin seulement se produire une fois le pointeur récupéré.

Il semblait bien fonctionner dans tous les tests. Je me suis accroché plus tard en ayant besoin d'optimiser la boucle interne.