Recent

Author Topic: try except  (Read 591 times)

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
try except
« on: March 07, 2023, 04:37:10 pm »
Hello,
I am wondering how the extension of try..except block affects the compiled program.

So, what is the difference in compiled output between this:

Code: Pascal  [Select][+][-]
  1.  
  2.   // [other code]
  3.  
  4.   try
  5.     AProcThatDoesNotFail(); // ... does not fail, so does not strictly need to stay here
  6.     AProcThatCanFail();
  7.   except
  8.  
  9.   // [other code]
  10.  

and this:

Code: Pascal  [Select][+][-]
  1.  
  2.   // [other code]
  3.  
  4.   AProcThatDoesNotFail();
  5.   try
  6.     AProcThatCanFail();
  7.   except
  8.  
  9.   // [other code]
  10.  

I know from a previous post in this forums that try..except block tells something like "in event of exception jump to first exception handling block, but I was wondering how this gets actually implemented and what is the effect of a bigger sequence of instructions to be "included in this handling" (for example it could be that before starting the try..except block some kind of callback is registered so that on a exception this calback is executed, and in this case the length of the sequence doesn't matter, i dont' know, I am just curious).

Thank you
« Last Edit: March 07, 2023, 04:44:55 pm by tt »
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: try except
« Reply #1 on: March 07, 2023, 04:45:51 pm »
AprocThatDoesNotFail?

When it does fail anyway the first will catch the exception, the second not..
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: try except
« Reply #2 on: March 07, 2023, 04:49:21 pm »
AprocThatDoesNotFail?

When it does fail anyway the first will catch the exception, the second not..

:) yes Thaddy, thank you. Sorry, I expressed my question badly, I added a more complete explanation of what I was wondering, hope I explained better.

I am not curious about the trapping capability of the compiled program, but how is binarily structured.
« Last Edit: March 07, 2023, 04:51:29 pm by tt »
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Warfley

  • Hero Member
  • *****
  • Posts: 1499
Re: try except
« Reply #3 on: March 07, 2023, 07:31:01 pm »
Depends on the way exceptions are implemented. In the fallback/default implementation a try-except block is nothing other than a setjmp/longjmp:
Code: Pascal  [Select][+][-]
  1. try
  2.   Code1
  3. except
  4.   Code2
  5. end;
  6.  
  7. // Basically is
  8. // Try:
  9. ExceptContext.Prev := ExceptStack; // backwards linked list
  10. ExceptStack := @ExceptContext;
  11. if SetJmp(ExceptStack^.Context) <> 0 then
  12. begin // Except block
  13.   Code2;
  14.   goto ExceptEnd;
  15. end;
  16. // Try block
  17. Code1;
  18. // End of try-except block
  19. ExceptEnd:
  20. ExceptStack := ExceptStack^.Prev; // Restore old exception context
When Code1 raises an exception it calls longjmp:
Code: Pascal  [Select][+][-]
  1. try
  2.   raise Exception.Create;
  3. except on E: Exception do
  4.   Writeln(E.Message);
  5. end;
  6.  
  7. // Basically is
  8. // Try:
  9. ExceptContext.Prev := ExceptStack; // backwards linked list
  10. ExceptStack := @ExceptContext;
  11. if SetJmp(ExceptStack^.Context) <> 0 then
  12. begin // Except block
  13.   E := ExceptStack^.Exception;
  14.   WriteLn(E.Message);
  15.   goto ExceptEnd;
  16. end;
  17. // Try block
  18. // raise:
  19. ExceptStack^.Exception := Exception.Create;
  20. LongJmp(ExceptStack^.Context, 1);
  21. // End of try-except block
  22. ExceptEnd:
  23. ExceptStack := ExceptStack^.Prev; // Restore old exception context

But there are other exception models, on Windows usually SEH (Structured Exception Handling) is used, which is provided by the OS (and has a better performance than setjmp/longjmp). For LLVM LLVM exceptions can be used, the implementation of which is then chosen by the backend (e.g. SEH for Windows)
« Last Edit: March 07, 2023, 07:34:41 pm by Warfley »

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: try except
« Reply #4 on: March 08, 2023, 03:17:53 pm »
Depends on the way exceptions are implemented. In the fallback/default implementation a try-except block is nothing other than a setjmp/longjmp:
Code: Pascal  [Select][+][-]
  1. try
  2.   Code1
  3. except
  4.   Code2
  5. end;
  6.  
  7. // Basically is
  8. // Try:
  9. ExceptContext.Prev := ExceptStack; // backwards linked list
  10. ExceptStack := @ExceptContext;
  11. if SetJmp(ExceptStack^.Context) <> 0 then
  12. begin // Except block
  13.   Code2;
  14.   goto ExceptEnd;
  15. end;
  16. // Try block
  17. Code1;
  18. // End of try-except block
  19. ExceptEnd:
  20. ExceptStack := ExceptStack^.Prev; // Restore old exception context
When Code1 raises an exception it calls longjmp:
Code: Pascal  [Select][+][-]
  1. try
  2.   raise Exception.Create;
  3. except on E: Exception do
  4.   Writeln(E.Message);
  5. end;
  6.  
  7. // Basically is
  8. // Try:
  9. ExceptContext.Prev := ExceptStack; // backwards linked list
  10. ExceptStack := @ExceptContext;
  11. if SetJmp(ExceptStack^.Context) <> 0 then
  12. begin // Except block
  13.   E := ExceptStack^.Exception;
  14.   WriteLn(E.Message);
  15.   goto ExceptEnd;
  16. end;
  17. // Try block
  18. // raise:
  19. ExceptStack^.Exception := Exception.Create;
  20. LongJmp(ExceptStack^.Context, 1);
  21. // End of try-except block
  22. ExceptEnd:
  23. ExceptStack := ExceptStack^.Prev; // Restore old exception context

But there are other exception models, on Windows usually SEH (Structured Exception Handling) is used, which is provided by the OS (and has a better performance than setjmp/longjmp). For LLVM LLVM exceptions can be used, the implementation of which is then chosen by the backend (e.g. SEH for Windows)

Thanks for the very good explanation, this clarifies my doubt.
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

 

TinyPortal © 2005-2018