• Aucun résultat trouvé

ka sortie est restreinte aux instructions évaluées entre les ins- tructionsst6rt_tr6ceetend_tr6ce. k’interpréteurinterp_mod6l

a changé de mode d’évaluation dynamiquement, pendant l’exécu- tion d’un programme, et ce sans que le code source des interpré- teurs précédents n’ait été modiǤé. b’est le changement dynamique du lien de délégation par prototype, autorisé par le langage, qui nous permet ce détournement.

ke détournement de cet exemple est rendu possible parce que l’on a un contrôle total sur la structure de l’interpréteur : on a pro- Ǥté du fait que toutes les fonctions d’évaluation étaient regroupées dans un même objet rules. cans marcissus, ce n’est pas le cas : l’évaluation de chaque terme se fait au sein d’une même fonction. conc le changement dynamique de prototype peut permettre le détournement, tant que les pièces du programme que l’on cherche à détourner sont regroupées au sein d’un même objet.

.

En programmation par aspects

Aspecti permet aussi de modiǤer une classe pendant l’exécution du programme, mais avant que cette classe ne soit char- gée dans la machine virtuelle. lais nous n’utiliserons pas cette fonctionnalité.

ka programmation par aspects est un mécanisme de détourne- ment tout trouvé. Avec Aspecti, on peut potentiellement modiǤer n’importe quel interpréteur en iava à la compilation, et sans avoir à directement modiǤer le code de la classe.

oar exemple, pour l’interpréteur arithmétique que l’on a déjà vu en iava :

interf6ce Term { int ev6l(); } cl6ss Num implements Term {

int n;

Num(int n) { this.n = n; } int ev6l() { return n; } }

cl6ss Plus implements Term { Term 6, b;

Plus(Term 6, Term b) { this.6 = 6; this.b = b; } int ev6l() {

return 6.ev6l() + b.ev6l(); } }

nn peut ajouter l’évaluation alternative deNumpar un aspect :

6spect NumDouble {

pointcut ev6l(Num num):

c6ll(int ev6l()) && t6rget(num); int 6round(Num num): ev6l(num) {

return * proceed(num); }

escap Variations de détournement sur un interpréteur minimal

dn compilant l’aspect NumDouble avec l’interpréteur de base, on obtient l’interpréteur modiǤé pour lequel toutes les évaluations de termesNumont une valeur doublée.

k’aspect est déǤni dans un Ǥchier à part, séparé du code de l’interpréteur. ka modiǤcation du code est eǣectuée par le tisseur d’aspects, lorsque l’on invoque la compilation de l’aspect par6jc, le compilateur d’Aspecti. nn peut aussi compiler le programme sans l’aspect, avec le compilateur j6v6c, et on obtient l’interpré- teur au comportement standard. ka programmation par aspects permet donc le détournement de cet interpréteur, mais dans cet exemple le détournement est statique : il se fait à la compilation.

nn peut reproduire l’exemple d’activation dynamique de la trace d’évaluation développé en iavarcript. À l’interpréteur des Num et desPlusprécédent, on rajoute l’évaluation du termeTr6ce:

cl6ss Tr6ce implements Term { Term e;

Tr6ce(Term e) { this.e = e; }

public int ev6l() { return e.ev6l(); } }

ke termeTr6cene fait que retourner l’évaluation du terme qu’il contient. nn peut construire un programmee qui l’utilise :

nn fait du termeTr6ce une expres- sion plutôt qu’une instruction (state-

ment) à l’inverse de l’exemple iavar-

cript, mais les deux formes sont réali- sables en programmation par aspects.

m6in() {

Term e = new Plus(

new Tr6ce(new Plus(new Num( ), new Num( ))), new Num( ));

e .ev6l(); //:

}

oour l’instant, le terme Tr6ce ne consigne rien sur la sortie standard. b’est le rôle de l’aspectDyn6micTr6ce:

1 6spect Dyn6micTr6ce {

2 pointcut tr6cedEv6l(Term t): 3 c6ll(int ev6l()) && t6rget(t)

4 && cflow(c6ll(int ev6l()) && t6rget(Tr6ce)); 5

6 before(Term t): tr6cedEv6l(t) { 7 System.out.println("ev6l " + t);

8 }

9 }

uoir p.censièrepour une explication de la couplecflow.

ka coupe tr6cedEv6l intercepte tous les appels de ev6l qui sont dans l’étendue d’un appel àTr6ce.ev6l. ka coupecflowins- pecte la pile d’appels, et on s’intéresse uniquement aux appels à

ev6l qui sont faits lorsque Tr6ce.ev6l est déjà présente sur la pile. oour tous les appels qui correspondent, on exécute l’aǦchage ligne 7 dans la méthode d’aspect before. ka sortie standard de l’évaluation du programmee est donc :

. . En programmation par aspects .escarole

ev6l Tr6ce@ ev6l Plus@ b ev6l Num@ f ev6l Num@

hl y a quatre lignes, qui correspondent aux trois termes évalués à l’intérieur du Tr6ce, ainsi que l’évaluation du Tr6ce. kes deux autres termes PlusetNum sont bien évalués, mais pas consignés. k’activation de la trace est donc limitée par le programme évalué, et non plus incluse statiquement pour tout l’interpréteur. ka pro- grammation par aspects permet donc le détournement dynamique de l’interpréteur.

En JavaScript

lalheureusement, les outils de programmation par aspects en iavarcript sont moins développés qu’Aspecti. ka solution la plus ǥexible est certainement Aspectrcript zsks10], qui permet d’insé- rer des aspects dynamiquement, et même de capturer les aǣecta- tions aux variables à l’intérieur des appels de fonction.

oour le module iavarcript suivant :

v6r m = (function() { v6r 6 = ; function f(x) { return x + 6; } function g(x) { return f(x); } return {g: g, f: f}; }());

nn peut intercepter les appels àfou les lectures de 6dans la fonctionfen utilisant Aspectrcript ainsi :

AspectScript.6round( AspectScript.Pointcuts.exec(m.f), function (jp) { return * jp.proceed() }) AspectScript.6round( AspectScript.Pointcuts.get('6'), function(jp) { return })

ke premier aspect capture les exécutions de la fonction f du modulempour en doubler le résultat. ke second aspect capture la référence faite à6 dans le corps de fpour modiǤer la valeur re- tournée : sans l’aspect,6vaut 1 à l’intérieur du module car c’est une variable capturée lexicalement. Avec l’aspect, on peut modi- Ǥer la valeur de cette variable lexicale, et donc simuler une portée dynamique.

esclandre Variations de détournement sur un interpréteur minimal

lais Aspectrcript a deux inconvénients majeurs qui sont la per- formance et la compatibilité avec le standard iavarcript. oour cap- turer et redéǤnir les évaluations, Aspectrcript déǤnit son propre analyseur de syntaxe, et réécrit le programme ciblé pour ensuite le réinterpréter. be procédé, qui donne à Aspectrcript sa ǥexibilité, rend le programme 5 à 15 fois plus lent. ouisque Aspectrcript réin- terprète le programme ciblé, il introduit également des variations indésirables avec le comportement d’un interpréteur standard. oar exemple, la constructionwithn’est pas supportée.

uoir p.pristinpour davantage de détails sur le fonctionnement d’Aspectrcript et ses inconvénients pour détourner marcis- sus.