2017-07-17 6 views
0

Lorsqu'un compilateur utilise le formulaire SSA pour représenter le code, les mises à jour des variables locales deviennent de nouvelles variables. Mais cela ne fonctionne pas toujours lorsque la variable est dans une portée englobante, par ex. (En utilisant la syntaxe JavaScript pour illustration, la situation pourrait se produire dans de nombreuses langues):Représentation SSA de la mise à jour d'une variable dans une zone englobante

function f() { 
    var x = 1; 
    function g() { 
     x++; 
    } 
    ... 
} 

Quelle est la façon habituelle de représenter cela?

Répondre

2

Une variable libre mutable utilisée dans une fermeture (x dans votre exemple) doit être implicitement "encadrée".

Il y a deux problèmes à considérer. Premièrement, la durée de vie: la variable peut survivre à la portée dans laquelle elle a été créée. (f pourrait retourner g, ou le stocker dans un conteneur persistant.) Deuxièmement, le partage: la variable peut être modifiée par f, g, ou toute autre fonction créée par f.

La solution la plus simple consiste à remplacer la variable par une "boîte" (un conteneur d'un objet qui est la valeur de la variable). La boîte elle-même est immuable (c'est-à-dire que le nom fait toujours référence à la même boîte). La modification et la référence à la valeur de la variable deviennent des méthodes d'établissement de conteneur et de getter. Bien sûr, le stockage de la valeur doit être dynamiquement alloué et récupéré lorsqu'il n'est plus nécessaire (comme avec n'importe quel conteneur).

Des optimisations sont disponibles dans certains cas, voire dans la plupart des cas. Tout d'abord, si la variable n'est jamais modifiée, il peut être possible de donner à chaque fermeture une copie de la valeur au lieu d'encadrer la valeur.

En second lieu, si la variable est non partagée - il est pas fermé par une autre fonction créée par l'exécution de f et il n'est pas référencé par f après la création de g - la variable pourrait simplement être déplacé dans g ' s fermeture. En effet, dans les deux cas ci-dessus, la fermeture elle-même devient la boîte, mais ceci a l'avantage de ne pas nécessiter une allocation dynamique séparée. Prouver la validité de ces optimisations dans un programme particulier nécessite une bonne analyse statique. Le premier est simple, puisque la modification est facile à détecter syntaxiquement, mais la seconde nécessite une analyse de flux (au moins). Dans ce qui précède, j'ai utilisé une description prudente des circonstances dans lesquelles l'optimisation pourrait être appliquée, ce qui ne nécessite qu'une analyse de flux simple; la détection d'autres applications possibles est plus compliquée.