• Aucun résultat trouvé

Exceptions et aspects

5.2 Constructions particulières des langages à aspect

5.2.2 Exceptions et aspects

Nous introduisons les exceptions dans le langage de base en utilisant les instructions sui-vantes :

S ::=tryS1 catchex S2 | throwex | . . .

L’instructiontryS1 catchex S2 déclare une nouvelle exceptionexqui peut être levée pen-dant l’exécution de S1 et capturée pendant l’exécution de S2. L’instruction throw ex lève l’exceptionex.

L’état abstraitΣcontient une pileΣE qui contient toutes les exceptions qui ont été déclarées. Chaque élément de ΣE est une paire de type I ×C où I est l’ensemble des identificateurs des exceptions et C un code. Une paire (ex, C) de ΣE fournie le code C à exécuter lorsque l’exceptionexest attrapée. Ces paires sont placées dans la pile dans l’ordre des déclarations des blocstry-catch. Lorsqu’une exceptionexest levée, la continuation courante est remplacée par le code associé àexdansΣE. Si l’exception ne se trouve pas dansΣE, le programme s’arrête avec une erreur dynamique de type "uncaught exception".

La sémantique des exceptions est décrite par la relation →b ci-dessous. L’exécution d’un bloctryS1 catchex S2, place dansΣE la paire(ex, S2 :C)et exécute le blocS1. L’instruc-tionpope retire cette paire deΣE après l’exécution deS1. Lorsqu’une exceptionex est levée, la continuation couranteCest remplacée par le codeC associé à la première occurrence deex

dansΣE. Toutes les exceptions sauvegardées aprèsexsont retirées deΣE; en effet, une levée d’exception supprime toutes les exceptions introduites depuis sa déclaration.

TRY

(tryS1catchex S2 :C, X∪ΣE) →b (S1 :pope :C, X∪(ex, S2 :C) : ΣE)

POPe ΣE =x: ΣE (pope:C, X∪ΣE) →b (C, X∪ΣE) THROW ΣE = (ex0, C0) :. . .: (exk, Ck) : (ex, C ) : ΣE (throwex:C, X∪ΣE) →b (C, X∪ΣE) avecexi 6=exet0≤i≤k UNCAUGHT (throwex :C, X ∪(ex0, C0) :. . .: (exk, Ck) :ǫ) →b ”Uncaught exception” avecexi 6=exet0≤i≤k

Le langage AspectJ, utilise les constructions syntaxiques telles quearound throws,

after throwing et handler, pour prendre en compte les exceptions dans les aspects. Nous présentons maintenant la sémantique de ces constructions.

AspectsAround throws

Un aspectaround throwsP Pexfiltre une instruction qui est filtrée parP et qui pourrait lever une exception filtrée par Pex. Son exécution est celle d’un aspect around dans lequel le point de coupure et le filtrage est modifié afin de prendre en compte les exceptions. Nous utilisons la grammaire suivante pourPex

Pex ::=∗ | id

où∗représente toutes les exceptions etidl’identificateur d’une exception. Nous utilisons aussi la fonctionexcepqui prend une instruction et retourne la liste des exceptionslexque ce point de jonction peut lever. Ainsi, la fonctionmatchexretournetrue s’il existe au moins une exception dans la liste des exceptions qui est filtrée par le motif des exceptions Pex (matchex(lex,∗) =

true). Un aspectaround throwsest décrit en redéfinissantΣψ. Cette définition, qui effectue un tissage statique, associe chaque instruction à la liste d’exceptions qu’elle peut lever. Un aspectaround throwsP Pexest donc défini par la fonctionΣψ ci-dessous.

Σψ(i:C, X∪ΣP) = if match(P, i)∧matchex(excep(i), Pex)

then(σ(test φ) :C, X∪i: ΣP)else nil

avecσ tel que σ(P) =i

AspectsAfter throwing

Les aspectsafter throwings’appliquent sur les procédures qui propagent des excep-tions à l’exécution. Nous supposons que les appels de procédure et leurs retours sont formalisés en utilisant la pile ΣF comme dans la Section 5.2.1, page 96. La pile ΣF contient toutes les signatures des appels de procédures en train de s’exécuter. Pour filtrer un appel de procédure qui propage une exception, la pile ΣF, l’exception et la continuation lorsqu’on entre dans un bloctry- catch, doivent être sauvegardées. Les deux règles TRY et POPe précédentes sont donc redéfinies comme suit :

TRY

(tryS1 catchex S2 :C, X∪ΣF ∪ΣE)

b (S1 :pope :C, X ∪ΣF ∪(ex, S2 :C,ΣF) : ΣE)

POPe ΣE =x: ΣE

(pope :C, X∪ΣF ∪ΣE) →b (C, X∪ΣF ∪ΣE)

Lorsqu’une exception est levée, le programme est remplacé par le code C

associé à cette exception et la pileΣE est modifiée comme dans la règle THROW précédente. Au lieu de rem-placer la pile couranteΣF par la pileΣ′F associée à l’exception levée,ΣF est modifiée récursi-vement par l’instructionRetp. Ce processus itératif nous permettra de filtrer tous les appels de procédures dansΣF qui ont propagé cette exception.

THROW ΣE = (ex0, C0F0) :. . .: (exk, CkFk) : (ex, C

F) : ΣE

(throwex:C, X∪ΣF ∪ΣE)

b (Retp exΣF :C

, X∪ΣF ∪ΣE)avecexi 6=exet0≤i≤k

La fonctionRetpexΣ′F retire le sommet de la pileΣF jusqu’à ce qu’elle soit égale à la va-leur qu’elle avait à l’entrée du bloctry-catchcorrespondant à l’exceptionex(règle RET1p). Chaque signature retirée, est celle d’une instruction qui a propagé l’exceptionexet donc can-didate à l’insertion d’une actionafter throwing. La règle RET2p exécute la continuation de l’exception lorsque ΣF possède la valeur qu’elle avait à l’entrée du bloctry-catch cor-respondant à l’exception qui a été propagée.

RET1p

(Retp exΣF :C, X∪(t)p: ΣF ∪ΣE) →b (Retp exΣF :C, X ∪ΣF ∪ΣE)

RET2p

(Retp exΣF :C, X∪ΣF ∪ΣE) →b (C, X ∪ΣF ∪ΣE)

Si l’aspect after throwing Σψ filtre l’appel de procédure p() correspondant à la si-gnature qui est au sommet de ΣF et p propageant l’exception ex, alors l’action de l’aspect

after throwingest placée au sommet de la continuation associée à exet la signature de

pest taguée. Ainsi, l’instruction correspondant à cette signature ne sera pas de nouveau filtrée et pourra être retirée deΣF parRetp exΣ′F. Cela est nécessaire afin de garantir que le tissage termine. Notons qu’iciΣψ filtre l’instruction au sommet deΣF contrairement aux fonctionsΣψ

précédentes qui filtraient l’instruction courante.

Σψ(RetpexΣ′F :C, X ∪(t)p: ΣF ∪ΣE) =

if match(P, p())then(Retp exΣ′F :σ(test φ) :C, X∪(t)p: ΣF ∪ΣE)else nil

avecσ tel que σ(P) =p()

EXEMPLE29. Considérons le programmeP roget l’aspectΣψ défini comme suit

P rog = tryf oo()catchex1 ǫ

void f oo()ex1 = goo()

void goo()ex1 = throw ex1

la déclaration des procédures est modifiée pour permettre de spécifier qu’elles puissent pro-pager une exception (T proc p()ex S). P rog appelle la procédure foo dans un bloctry

-catch. Cette procédure, qui peut propager une exceptionex1, appelle la procédure gooqui lèveex1.

Σψ = φ

avecP = (x)x

φ(Σ) = baz()

L’aspectΣψ tisse un appel àbazaprès tout appel de procédure se terminant en retournant une exception. La réduction deP rog avec l’aspectΣψ est celle-ci :

(start:tryf oo()catchex1ǫ:•, X ∪ǫ∪ǫ)

→ (tryf oo()catchex1ǫ:•, X ∪ǫ∪ǫ)

→ (f oo() :pope:•, X ∪ǫ∪(ex1, ǫ, ǫ) :ǫ)

→ (goo() :{pope :•}, X ∪(void)f oo :ǫ∪(ex1, ǫ, ǫ) :ǫ)

→ (throwex1 :{{pope :•}}, X∪(void)goo: (void)f oo:ǫ∪(ex1, ǫ, ǫ) :ǫ)

→ (Retpex1ǫ:•, X ∪(void)goo: (void)f oo :ǫ∪ǫ)

→ (Retpex1ǫ:test φ:•, X ∪(void)goo: (void)f oo :ǫ∪ǫ)

→ (Retpex1ǫ:test φ:test φ:•, X ∪(void)f oo :ǫ∪ǫ)

→ (Retpex1ǫ:test φ:test φ:•, X ∪ǫ∪ǫ)

→ (test φ:test φ:•, X ∪ǫ∪ǫ)

→ (baz() :test φ:•, X ∪ǫ∪ǫ)

→ ({test φ:•}, X∪(void)baz :ǫ∪ǫ)

→ (test φ:•, X∪ǫ∪ǫ)

→ (baz() :•, X ∪ǫ∪ǫ)

→ ({ǫ:•}, X ∪(void)baz :ǫ∪ǫ)

→ (ǫ•, X ∪ǫ∪ǫ)

Lorsqu’une exception est levée, la continuation courante est remplacée par le code du bloc

catch ex1 (ici, ǫ) etRetp ex1 qui va récursivement retirer de la pileΣF les deux signatures qui ont propagé l’exception levée. A chaque fois, l’aspectΣψ insère l’appel àbaz.

Point de coupure Handler

Dans AspectJ, le point de coupure handler Pex, filtre tout point de jonction qui attrape une exception ex (c.-à-d.,catch ex) filtrée par le motif Pex. Il est supporté uniquement par les aspectsbefore. Lorsqu’une exception est levée, comme dans le cas de la règle THROW, la continuation courante est remplacée par le code associé à l’exception levée (c.-à-d.,le code du bloccatchqui attrape l’exception). L’aspectΣψ insère donc son action (test φ) avant ce code si l’exception levée est filtrée parPex.

Σψ(throwex:C, X∪(ex0, C0) :. . .: (exk, Ck) : (ex, C) : ΣE) =

ifmatchex(ex, Pex)then(test φ:C

, X∪ΣE)

avecexi 6=exet0≤i≤k