Metody realizacji języków programowania/MRJP Wykład 10: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Ben (dyskusja | edycje)
Nie podano opisu zmian
Ben (dyskusja | edycje)
Nie podano opisu zmian
Linia 105: Linia 105:


{|
{|
|- | Od || Do || Bloki catch  
|-  
|- |1   || 1  || C1  
| Od  
|- |2   || 2  || C1, C2  
| Do  
|- |3   || 6  || C1  
| Bloki catch  
|-  
|1
| 1  | C1  
|-  
|2
| 2  | C1, C2  
|-  
|3
| 6  | C1  
|}
|}



Wersja z 11:35, 20 wrz 2006

Wyjątki

  • Pojęcie wyjątek oznacza błąd (nietypową, niepożądaną

sytuację).

  • Obsługa wyjątków oznacza reakcję programu na wykryte błędy.
  • Funkcja, która napotkała problem zgłasza (rzuca)

wyjątek.

  • Wyjątek jest przekazywany do miejsca wywołania funkcji, gdzie

może być wyłapany i obsłużony albo przekazany wyżej. Innymi słowy poszukiwania bloku obsługi wyjątku dokonywane są połańcuchu DL.

  • Przy wychodzeniu z funkcji i bloków usuwane są obiekty automatyczne.


Składnia

Dla ustalenia uwagi przyjmiemy składnię C++ (składnia Javy jest w tej kwestii bardzo podobna)

Zgłoszenie wyjątku

 throw <wyrażenie>

Obsługa wyjątków

 try {
   <instrukcje>
 } catch(<parametr 1>) {
   <obsługa wyjątku 1>
 //...
 } catch(<parametr n>) {
   <obsługa wyjątku n>
 }


Semantyka

  • Gdy któraś z instrukcji w części try przekazała

wyjątek, przerywamy wykonanie tego ciągu i szukamy catch z odpowiednim parametrem.

  • Jeśli znajdziemy, to wykonujemy obsługę tego wyjątku, a po jej

zakończeniu instrukcje po wszystkich blokach catch.

  • Jeśli nie znajdziemy, przechodzimy do miejsca wywołania

(usuwając obiekty automatyczne bieżącej funkcji) i kontynuujemy poszukiwanie.

  • Jeśli nie znajdziemy w żadnej z aktywnych funkcji, wykonanie

programu zostanie przerwane.

Implementacja obsługi wyjątków

Obsługę wyjątków można zrealizować na wiele różnych sposobów. Bardzo istotne jest jednak to, aby narzut (dodatkowy czas wykonania programu i zużyta pamięć) przy normalnym (tj. bez wystąpienia wyjątków) wykonaniu programu był minimalny, a w miarę możności zerowy. Z tego punktu widzenia realizacje wymagające wykonania dodatkowych czynności na początku i końcu bloku try można uznać za nieefektywne.

Bliższe spojrzenie na semantykę wyjątków, ujawnia, że w momencie zgłoszenia wyjątku muszą zostać wykonane następujące czynności:

  • stwierdzenie, czy nastąpiło ono wewnątrz bloku try
  • identyfikacja aktywnych bloków try - moze być więcej niż jeden, np.
h() {
  try {
    f();
    try {
      g(); // tu wyjątek
    }
    catch E1 { ... }
  }
  catch E2 { ... }
}  
  • rozpoznanie typu zgłoszonego wyjątku
  • próba dopasowania do typu wyjątku jednego z bloków catch
  • w wypadku powodzenia wykonanie tego bloku
  • w przeciwnym wypadku przekazanie wyjątku w górę DL

Identyfikacja aktywnych bloków try

Dla identyfikacji aktywnych bloków try, w czasie wykonania programu musi być dostępna informacja (struktura danych), która dla każdej instrukcji pozwoli ustalić czy i jakie bloki try ją otaczają. Jeżeli chcemy uniknąć narzutu dla 'prawidłowego' przebiegu programu, informacja taka musi być w całości wygenerowana w czasie kompilacji.

Prostą a efektywną metodą spełniającą te wymagania jest użycia tablicy indeksowanej adresami instrukcji (a raczej zakresami adresów, w przeciwnym bowiem przypadku tablica miałaby rozmiar zbliżony do całkowitej liczby instrukcji programu). Elementami tej tablicy będą listy odpowiednich bloków try, lub listy odpowiednich bloków catch

Przykład

Rozważmy przytoczony wcześniej przykład funkcji:

h() {
  try {
    f();
    try {
      g(); // tu wyjątek
    }
    catch E1 { I1; }
  }
  catch E2 { I2; }
  I3;
} 

gdzie I1, I2,I3 są instrukcjami niezgłaszającymi wyjątków

Załóżmy przy tym, że wygenerowany dla niej został następujący kod maszynowy:

 0: enter
 1: call f
 2: call g
 3: jmp 7
 4: I1
 5: jmp 7
 6: I2
 7: I3
 8: leave
 9: ret
 

Tablica, o której mowa wyglądać będzie następująco

Od Do Bloki catch
1 C1
2 C1, C2
3 C1


Test:

The table's caption
cell codes go here
cells in the next row go here more cells in the same row here