delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/05/20/23:11:13

From: "Andrew Crabtree" <andrewc AT rosemail DOT rose DOT hp DOT com>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: New exception & assembly language
Date: Wed, 20 May 1998 16:23:15 -0700
Organization: Hewlett-Packard, Roseville
Lines: 70
Message-ID: <6jvol4$499$1@rosenews.rose.hp.com>
References: <35620fc6 DOT 4685212 AT news1 DOT bway DOT net>
NNTP-Posting-Host: ros51675cra.rose.hp.com
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

Josh Rubin wrote in message <35620fc6 DOT 4685212 AT news1 DOT bway DOT net>...
>Suppose an assembly language routine calls a C++ function.
>Does the new exception handling mechanism require that
>the assembly language routine do anything special for
>stack unwinding in case an exception is thrown?
This might help.  Its from the file except.c in gcc/cp directory

Andy

/* ======================================================================
   Briefly the algorithm works like this:

     When a constructor or start of a try block is encountered,
     push_eh_entry (&eh_stack) is called.  Push_eh_entry () creates a
     new entry in the unwind protection stack and returns a label to
     output to start the protection for that block.

     When a destructor or end try block is encountered, pop_eh_entry
     (&eh_stack) is called.  Pop_eh_entry () returns the eh_entry it
     created when push_eh_entry () was called.  The eh_entry structure
     contains three things at this point.  The start protect label,
     the end protect label, and the exception handler label.  The end
     protect label should be output before the call to the destructor
     (if any). If it was a destructor, then its parse tree is stored
     in the finalization variable in the eh_entry structure.  Otherwise
     the finalization variable is set to NULL to reflect the fact that
     it is the end of a try block.  Next, this modified eh_entry node
     is enqueued in the finalizations queue by calling
     enqueue_eh_entry (&queue,entry).

 +---------------------------------------------------------------+
 |XXX: Will need modification to deal with partially  |
 |   constructed arrays of objects  |
 |        |
 | Basically, this consists of keeping track of how many |
 | of the objects have been constructed already (this |
 | should be in a register though, so that shouldn't be a |
 | problem.      |
 +---------------------------------------------------------------+

     When a catch block is encountered, there is a lot of work to be
     done.

     Since we don't want to generate the catch block inline with the
     regular flow of the function, we need to have some way of doing
     so.  Luckily, we can use sequences to defer the catch sections.
     When the start of a catch block is encountered, we start the
     sequence.  After the catch block is generated, we end the
     sequence.

     Next we must insure that when the catch block is executed, all
     finalizations for the matching try block have been completed.  If
     any of those finalizations throw an exception, we must call
     terminate according to the ARM (section r.15.6.1).  What this
     means is that we need to dequeue and emit finalizations for each
     entry in the eh_queue until we get to an entry with a NULL
     finalization field.  For any of the finalization entries, if it
     is not a call to terminate (), we must protect it by giving it
     another start label, end label, and exception handler label,
     setting its finalization tree to be a call to terminate (), and
     enqueue'ing this new eh_entry to be output at an outer level.
     Finally, after all that is done, we can get around to outputting
     the catch block which basically wraps all the "catch (...) {...}"
     statements in a big if/then/else construct that matches the
     correct block to call.




- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019