Commit 76fc91c7 by Mark Mitchell Committed by Mark Mitchell

except.h (eh_status): Adjust documentation for x_protect_list.

	* except.h (eh_status): Adjust documentation for x_protect_list.
	(begin_protect_partials): New function.
	* except.c (enqueue_eh_entry): Fix formatting.
	(get_first_handler): Add consistency check.
	(add_partial_entry): Adjust usage of protect_list.
	(emit_cleanup_handler): Save and restore ehqueue.
	(expand_start_all_catch): Add comment.
	(begin_protect_partials): New function.
	(end_protect_partials): Adjust usage of protect_list.
	(init_eh_for_function): Use xcalloc.

From-SVN: r30667
parent 913d0833
1999-11-25 Mark Mitchell <mark@codesourcery.com>
* except.h (eh_status): Adjust documentation for x_protect_list.
(begin_protect_partials): New function.
* except.c (enqueue_eh_entry): Fix formatting.
(get_first_handler): Add consistency check.
(add_partial_entry): Adjust usage of protect_list.
(emit_cleanup_handler): Save and restore ehqueue.
(expand_start_all_catch): Add comment.
(begin_protect_partials): New function.
(end_protect_partials): Adjust usage of protect_list.
(init_eh_for_function): Use xcalloc.
1999-11-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 1999-11-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* c-common.c (check_format_info): Don't call a variadic function * c-common.c (check_format_info): Don't call a variadic function
......
...@@ -643,13 +643,9 @@ enqueue_eh_entry (queue, entry) ...@@ -643,13 +643,9 @@ enqueue_eh_entry (queue, entry)
node->chain = NULL; node->chain = NULL;
if (queue->head == NULL) if (queue->head == NULL)
{ queue->head = node;
queue->head = node;
}
else else
{ queue->tail->chain = node;
queue->tail->chain = node;
}
queue->tail = node; queue->tail = node;
} }
...@@ -912,7 +908,10 @@ struct handler_info * ...@@ -912,7 +908,10 @@ struct handler_info *
get_first_handler (region) get_first_handler (region)
int region; int region;
{ {
return function_eh_regions[find_func_region (region)].handlers; int r = find_func_region (region);
if (r == -1)
abort ();
return function_eh_regions[r].handlers;
} }
/* Clean out the function_eh_region table and free all memory */ /* Clean out the function_eh_region table and free all memory */
...@@ -1097,7 +1096,15 @@ add_partial_entry (handler) ...@@ -1097,7 +1096,15 @@ add_partial_entry (handler)
with __terminate. */ with __terminate. */
handler = protect_with_terminate (handler); handler = protect_with_terminate (handler);
protect_list = tree_cons (NULL_TREE, handler, protect_list); /* For backwards compatibility, we allow callers to omit calls to
begin_protect_partials for the outermost region. So, we must
explicitly do so here. */
if (!protect_list)
begin_protect_partials ();
/* Add this entry to the front of the list. */
TREE_VALUE (protect_list)
= tree_cons (NULL_TREE, handler, TREE_VALUE (protect_list));
pop_obstacks (); pop_obstacks ();
} }
...@@ -1675,7 +1682,7 @@ expand_leftover_cleanups () ...@@ -1675,7 +1682,7 @@ expand_leftover_cleanups ()
entry; entry;
entry = dequeue_eh_entry (&ehqueue)) entry = dequeue_eh_entry (&ehqueue))
{ {
/* A leftover try bock. Shouldn't be one here. */ /* A leftover try block. Shouldn't be one here. */
if (entry->finalization == integer_zero_node) if (entry->finalization == integer_zero_node)
abort (); abort ();
...@@ -1788,6 +1795,13 @@ emit_cleanup_handler (entry) ...@@ -1788,6 +1795,13 @@ emit_cleanup_handler (entry)
{ {
rtx prev; rtx prev;
rtx handler_insns; rtx handler_insns;
struct eh_queue q;
/* Since the cleanup could itself contain try-catch blocks, we
squirrel away the current queue and replace it when we are done
with this function. */
q = ehqueue;
ehqueue.head = ehqueue.tail = NULL;
/* Put these handler instructions in a sequence. */ /* Put these handler instructions in a sequence. */
do_pending_stack_adjust (); do_pending_stack_adjust ();
...@@ -1828,6 +1842,10 @@ emit_cleanup_handler (entry) ...@@ -1828,6 +1842,10 @@ emit_cleanup_handler (entry)
emit_insns (handler_insns); emit_insns (handler_insns);
catch_clauses = get_insns (); catch_clauses = get_insns ();
end_sequence (); end_sequence ();
/* Now we've left the handler. */
expand_leftover_cleanups ();
ehqueue = q;
} }
/* Generate RTL for the start of a group of catch clauses. /* Generate RTL for the start of a group of catch clauses.
...@@ -1868,6 +1886,9 @@ expand_start_all_catch () ...@@ -1868,6 +1886,9 @@ expand_start_all_catch ()
the handlers in this handler-seq. */ the handlers in this handler-seq. */
start_sequence (); start_sequence ();
/* Throw away entries in the queue that we won't need anymore. We
need entries for regions that have ended but to which there might
still be gotos pending. */
for (entry = dequeue_eh_entry (&ehqueue); for (entry = dequeue_eh_entry (&ehqueue);
entry->finalization != integer_zero_node; entry->finalization != integer_zero_node;
entry = dequeue_eh_entry (&ehqueue)) entry = dequeue_eh_entry (&ehqueue))
...@@ -1989,17 +2010,44 @@ expand_rethrow (label) ...@@ -1989,17 +2010,44 @@ expand_rethrow (label)
emit_jump (label); emit_jump (label);
} }
/* Begin a region that will contain entries created with
add_partial_entry. */
void
begin_protect_partials ()
{
/* Put the entry on the function obstack. */
push_obstacks_nochange ();
resume_temporary_allocation ();
/* Push room for a new list. */
protect_list = tree_cons (NULL_TREE, NULL_TREE, protect_list);
/* We're done with the function obstack now. */
pop_obstacks ();
}
/* End all the pending exception regions on protect_list. The handlers /* End all the pending exception regions on protect_list. The handlers
will be emitted when expand_leftover_cleanups is invoked. */ will be emitted when expand_leftover_cleanups is invoked. */
void void
end_protect_partials () end_protect_partials ()
{ {
while (protect_list) tree t;
{
expand_eh_region_end (TREE_VALUE (protect_list)); /* For backwards compatibility, we allow callers to omit the call to
protect_list = TREE_CHAIN (protect_list); begin_protect_partials for the outermost region. So,
} PROTECT_LIST may be NULL. */
if (!protect_list)
return;
/* End all the exception regions. */
for (t = TREE_VALUE (protect_list); t; t = TREE_CHAIN (t))
expand_eh_region_end (TREE_VALUE (t));
/* Pop the topmost entry. */
protect_list = TREE_CHAIN (protect_list);
} }
/* Arrange for __terminate to be called if there is an unhandled throw /* Arrange for __terminate to be called if there is an unhandled throw
...@@ -2528,20 +2576,7 @@ void ...@@ -2528,20 +2576,7 @@ void
init_eh_for_function () init_eh_for_function ()
{ {
current_function->eh current_function->eh
= (struct eh_status *) xmalloc (sizeof (struct eh_status)); = (struct eh_status *) xcalloc (1, sizeof (struct eh_status));
ehstack.top = 0;
catchstack.top = 0;
ehqueue.head = ehqueue.tail = 0;
catch_clauses = NULL_RTX;
false_label_stack = 0;
caught_return_label_stack = 0;
protect_list = NULL_TREE;
current_function_ehc = NULL_RTX;
eh_return_context = NULL_RTX;
eh_return_stack_adjust = NULL_RTX;
eh_return_handler = NULL_RTX;
eh_return_stub_label = NULL_RTX;
} }
void void
......
...@@ -125,9 +125,10 @@ struct eh_status ...@@ -125,9 +125,10 @@ struct eh_status
normal control flow out of a handler (instead of, say, returning to normal control flow out of a handler (instead of, say, returning to
the caller of the current function or exiting the program). */ the caller of the current function or exiting the program). */
struct label_node *x_caught_return_label_stack; struct label_node *x_caught_return_label_stack;
/* A TREE_CHAINed list of handlers for regions that are not yet /* A stack (TREE_LIST) of lists of handlers. The TREE_VALUE of each
closed. The TREE_VALUE of each entry contains the handler for the node is itself a TREE_CHAINed list of handlers for regions that
corresponding entry on the ehstack. */ are not yet closed. The TREE_VALUE of each entry contains the
handler for the corresponding entry on the ehstack. */
union tree_node *x_protect_list; union tree_node *x_protect_list;
/* The EH context. Nonzero if the function has already /* The EH context. Nonzero if the function has already
fetched a pointer to the EH context for exception handling. */ fetched a pointer to the EH context for exception handling. */
...@@ -368,6 +369,11 @@ extern void expand_start_all_catch PROTO((void)); ...@@ -368,6 +369,11 @@ extern void expand_start_all_catch PROTO((void));
extern void expand_end_all_catch PROTO((void)); extern void expand_end_all_catch PROTO((void));
/* Begin a region that will contain entries created with
add_partial_entry. */
extern void begin_protect_partials PROTO((void));
#ifdef TREE_CODE #ifdef TREE_CODE
/* Create a new exception region and add the handler for the region /* Create a new exception region and add the handler for the region
onto a list. These regions will be ended (and their handlers onto a list. These regions will be ended (and their handlers
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment