Diff for /gforth/except.fs between versions 1.4 and 1.10

version 1.4, 2002/09/24 17:57:28 version 1.10, 2006/05/26 21:18:45
Line 1 Line 1
 \ catch, throw, etc.  \ catch, throw, etc.
   
 \ Copyright (C) 1999,2000 Free Software Foundation, Inc.  \ Copyright (C) 1999,2000,2003 Free Software Foundation, Inc.
   
 \ This file is part of Gforth.  \ This file is part of Gforth.
   
Line 33  Defer store-backtrace Line 33  Defer store-backtrace
 ' noop IS store-backtrace  ' noop IS store-backtrace
 \ [THEN]  \ [THEN]
   
 : (try) ( -- )  \ Ok, here's the story about how we get to the native code for the
     \ inline argument: address of the handler  \ recovery code in case of a THROW, and why there is all this funny
   \ stuff being compiled by TRY and RECOVER:
   
   \ Upon a THROW, we cannot just return through the ordinary return
   \ address, but have to use a different one, for code after the
   \ RECOVER.  How do we do that, in a way portable between the various
   \ threaded and native code engines?  In particular, how does the
   \ native code engine learn about the address of the native recovery
   \ code?
   
   \ On the Forth level, we can compile only references to threaded code.
   \ The only thing that translates a threaded code address to a native
   \ code address is docol, which is only called with EXECUTE and
   \ friends.  So we start the recovery code with a docol, and invoke it
   \ with PERFORM; the recovery code then rdrops the superfluously
   \ generated return address and continues with the proper recovery
   \ code.
   
   \ At compile time, since we cannot compile a forward reference (to the
   \ recovery code) as a literal (backpatching does not work for
   \ native-code literals), we produce a data cell (wrapped in AHEAD
   \ ... THEN) that we can backpatch, and compile the address of that as
   \ literal.
   
   \ Overall, this leads to the following resulting code:
   
   \   ahead
   \ +><recovery address>-+
   \ | then               |
   \ +-lit                |
   \   (try)              |
   \   ...                |
   \   (recover)          |
   \   ahead              |
   \   docol: <-----------+
   \   rdrop
   \   ...
   \   then
   \   ...
   
   \ !! explain handler on-stack structure
   
   : (try) ( ahandler -- )
     r>      r>
     dup @ >r \ recovery address      swap >r \ recovery address
     rp@ 'catch >r      rp@ 'catch >r
     sp@ >r      sp@ >r
     fp@ >r      fp@ >r
     lp@ >r      lp@ >r
     handler @ >r      handler @ >r
     rp@ handler !      rp@ handler !
     backtrace-empty on      >r ;
     cell+ >r ;  
   
 : try ( compilation  -- orig ; run-time  -- ) \ gforth  : try ( compilation  -- orig ; run-time  -- ) \ gforth
     POSTPONE (try) >mark ; immediate compile-only      \ !! does not work correctly for gforth-native
       POSTPONE ahead here >r >mark 1 cs-roll POSTPONE then
       r> POSTPONE literal POSTPONE (try) ; immediate compile-only
   
 : (recover) ( -- )  : (recover) ( -- )
     \ normal end of try block: restore handler, forget rest      \ normal end of try block: restore handler, forget rest
Line 63  Defer store-backtrace Line 106  Defer store-backtrace
 : recover ( compilation  orig1 -- orig2 ; run-time  -- ) \ gforth  : recover ( compilation  orig1 -- orig2 ; run-time  -- ) \ gforth
     \ !! check using a special tag      \ !! check using a special tag
     POSTPONE (recover)      POSTPONE (recover)
     POSTPONE else ; immediate compile-only      POSTPONE else
       docol: here 0 , 0 , code-address! \ start a colon def 
       postpone rdrop                    \ drop the return address
   ; immediate compile-only
   
 : endtry ( compilation  orig -- ; run-time  -- ) \ gforth  : endtry ( compilation  orig -- ; run-time  -- ) \ gforth
     POSTPONE then ; immediate compile-only      POSTPONE then ; immediate compile-only
Line 79  is catch Line 125  is catch
 :noname ( y1 .. ym error/0 -- y1 .. ym / z1 .. zn error ) \ exception  :noname ( y1 .. ym error/0 -- y1 .. ym / z1 .. zn error ) \ exception
     ?DUP IF      ?DUP IF
         [ here forthstart 9 cells + ! ]          [ here forthstart 9 cells + ! ]
         store-backtrace          store-backtrace error-stack off
         handler @ ?dup-0=-IF          handler @ ?dup-0=-IF
             cr ." uncaught exception: " .error cr              >stderr cr ." uncaught exception: " .error cr
             2 (bye)              2 (bye)
             quit  \           quit
         THEN          THEN
         rp!          rp!
         r> handler !          r> handler !
         r> lp!          r> lp!
         r> fp!          r> fp!
         r> swap >r sp! drop r>          r> swap >r sp! drop r>
         rdrop 'throw          rdrop 'throw r> perform
     THEN ;      THEN ;
 is throw  is throw
   [IFDEF] throw>error
   :noname ( y1 .. ym error/0 -- y1 .. ym / z1 .. zn error ) \ exception
       ?DUP IF
           handler @ ?dup-0=-IF
               >stderr cr ." uncaught exception: " .error cr
               2 (bye)
   \           quit
           THEN
           rp!
           r> handler !
           r> lp!
           r> fp!
           r> swap >r sp! drop r>
           rdrop 'throw r> perform
       THEN ;
   is throw>error
   [THEN]
   

Removed from v.1.4  
changed lines
  Added in v.1.10


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>