/* Handle exceptions for GNU compiler for the Java(TM) language.
   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.

This file is part of GNU CC.

GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.

Java and all Java-based marks are trademarks or registered trademarks
of Sun Microsystems, Inc. in the United States and other countries.
The Free Software Foundation is independent of Sun Microsystems, Inc.  */

#include "config.h"
#include "system.h"
#include "tree.h"
#include "real.h"
#include "rtl.h"
#include "java-tree.h"
#include "javaop.h"
#include "java-opcodes.h"
#include "jcf.h"
#include "function.h"
#include "except.h"
#include "java-except.h"
#include "toplev.h"

static void expand_start_java_handler PARAMS ((struct eh_range *));
static void expand_end_java_handler PARAMS ((struct eh_range *));
static struct eh_range *find_handler_in_range PARAMS ((int, struct eh_range *,
						      struct eh_range *));
static void link_handler PARAMS ((struct eh_range *, struct eh_range *));
static void check_start_handlers PARAMS ((struct eh_range *, int));
static void free_eh_ranges PARAMS ((struct eh_range *range));

extern struct obstack permanent_obstack;

struct eh_range *current_method_handlers;

struct eh_range *current_try_block = NULL;

struct eh_range *eh_range_freelist = NULL;

/* These variables are used to speed up find_handler. */

static int cache_range_start, cache_range_end;
static struct eh_range *cache_range;
static struct eh_range *cache_next_child;

/* A dummy range that represents the entire method. */

struct eh_range whole_range;

#if defined(DEBUG_JAVA_BINDING_LEVELS)
int binding_depth;
int is_class_level;
int current_pc;
extern void indent ();

#endif

/* Search for the most specific eh_range containing PC.
   Assume PC is within RANGE.
   CHILD is a list of children of RANGE such that any
   previous children have end_pc values that are too low. */

static struct eh_range *
find_handler_in_range (pc, range, child)
     int pc;
     struct eh_range *range;
     register struct eh_range *child;
{
  for (; child != NULL;  child = child->next_sibling)
    {
      if (pc < child->start_pc)
	break;
      if (pc < child->end_pc)
	return find_handler_in_range (pc, child, child->first_child);
    }
  cache_range = range;
  cache_range_start = pc;
  cache_next_child = child;
  cache_range_end = child == NULL ? range->end_pc : child->start_pc;
  return range;
}

/* Find the inner-most handler that contains PC. */

struct eh_range *
find_handler (pc)
     int pc;
{
  struct eh_range *h;
  if (pc >= cache_range_start)
    {
      h = cache_range;
      if (pc < cache_range_end)
	return h;
      while (pc >= h->end_pc)
	{
	  cache_next_child = h->next_sibling;
	  h = h->outer;
	}
    }
  else
    {
      h = &whole_range;
      cache_next_child = h->first_child;
    }
  return find_handler_in_range (pc, h, cache_next_child);
}

/* Recursive helper routine for check_nested_ranges. */

static void
link_handler (range, outer)
     struct eh_range *range, *outer;
{
  struct eh_range **ptr;

  if (range->start_pc == outer->start_pc && range->end_pc == outer->end_pc)
    {
      outer->handlers = chainon (outer->handlers, range->handlers);
      return;
    }

  /* If the new range completely encloses the `outer' range, then insert it
     between the outer range and its parent.  */
  if (range->start_pc <= outer->start_pc && range->end_pc >= outer->end_pc)
    {
      range->outer = outer->outer;
      range->next_sibling = NULL;
      range->first_child = outer;
      {
	struct eh_range **pr = &(outer->outer->first_child);
	while (*pr != outer)
	  pr = &(*pr)->next_sibling;
	*pr = range;
      }
      outer->outer = range;
      return;
    }

  /* Handle overlapping ranges by splitting the new range.  */
  if (range->start_pc < outer->start_pc || range->end_pc > outer->end_pc)
    {
      struct eh_range *h
	= (struct eh_range *) xmalloc (sizeof (struct eh_range));
      if (range->start_pc < outer->start_pc)
	{
	  h->start_pc = range->start_pc;
	  h->end_pc = outer->start_pc;
	  range->start_pc = outer->start_pc;
	}
      else
	{
	  h->start_pc = outer->end_pc;
	  h->end_pc = range->end_pc;
	  range->end_pc = outer->end_pc;
	}
      h->first_child = NULL;
      h->outer = NULL;
      h->handlers = build_tree_list (TREE_PURPOSE (range->handlers),
				     TREE_VALUE (range->handlers));
      h->next_sibling = NULL;
      /* Restart both from the top to avoid having to make this
	 function smart about reentrancy.  */
      link_handler (h, &whole_range);
      link_handler (range, &whole_range);
      return;
    }

  ptr = &outer->first_child;
  for (;; ptr = &(*ptr)->next_sibling)
    {
      if (*ptr == NULL || range->end_pc <= (*ptr)->start_pc)
	{
	  range->next_sibling = *ptr;
	  range->first_child = NULL;
	  range->outer = outer;
	  *ptr = range;
	  return;
	}
      else if (range->start_pc < (*ptr)->end_pc)
	{
	  link_handler (range, *ptr);
	  return;
	}
      /* end_pc > (*ptr)->start_pc && start_pc >= (*ptr)->end_pc. */
    }
}

/* The first pass of exception range processing (calling add_handler)
   constructs a linked list of exception ranges.  We turn this into
   the data structure expected by the rest of the code, and also
   ensure that exception ranges are properly nested.  */

void
handle_nested_ranges ()
{
  struct eh_range *ptr, *next;

  ptr = whole_range.first_child;
  whole_range.first_child = NULL;
  for (; ptr; ptr = next)
    {
      next = ptr->next_sibling;
      ptr->next_sibling = NULL;
      link_handler (ptr, &whole_range);
    }
}

/* Free RANGE as well as its children and siblings.  */

static void
free_eh_ranges (range)
     struct eh_range *range;
{
  while (range) 
    {
      struct eh_range *next = range->next_sibling;
      free_eh_ranges (range->first_child);
      if (range != &whole_range)
	free (range);
      range = next;
    }
}

/* Called to re-initialize the exception machinery for a new method. */

void
method_init_exceptions ()
{
  free_eh_ranges (&whole_range);
  whole_range.start_pc = 0;
  whole_range.end_pc = DECL_CODE_LENGTH (current_function_decl) + 1;
  whole_range.outer = NULL;
  whole_range.first_child = NULL;
  whole_range.next_sibling = NULL;
  cache_range_start = 0xFFFFFF;
}

/* Add an exception range.  If we already have an exception range
   which has the same handler and label, and the new range overlaps
   that one, then we simply extend the existing range.  Some bytecode
   obfuscators generate seemingly nonoverlapping exception ranges
   which, when coalesced, do in fact nest correctly.
   
   This constructs an ordinary linked list which check_nested_ranges()
   later turns into the data structure we actually want.
   
   We expect the input to come in order of increasing START_PC.  This
   function doesn't attempt to detect the case where two previously
   added disjoint ranges could be coalesced by a new range; that is
   what the sorting counteracts.  */

void
add_handler (start_pc, end_pc, handler, type)
     int start_pc, end_pc;
     tree handler;
     tree type;
{
  struct eh_range *ptr, *prev = NULL, *h;

  for (ptr = whole_range.first_child; ptr; ptr = ptr->next_sibling)
    {
      if (start_pc >= ptr->start_pc
	  && start_pc <= ptr->end_pc
	  && TREE_PURPOSE (ptr->handlers) == type
	  && TREE_VALUE (ptr->handlers) == handler)
	{
	  /* Already found an overlapping range, so coalesce.  */
	  ptr->end_pc = MAX (ptr->end_pc, end_pc);
	  return;
	}
      prev = ptr;
    }

  h = (struct eh_range *) xmalloc (sizeof (struct eh_range));
  h->start_pc = start_pc;
  h->end_pc = end_pc;
  h->first_child = NULL;
  h->outer = NULL;
  h->handlers = build_tree_list (type, handler);
  h->next_sibling = NULL;
  h->expanded = 0;

  if (prev == NULL)
    whole_range.first_child = h;
  else
    prev->next_sibling = h;
}


/* if there are any handlers for this range, issue start of region */
static void
expand_start_java_handler (range)
  struct eh_range *range;
{
#if defined(DEBUG_JAVA_BINDING_LEVELS)
  indent ();
  fprintf (stderr, "expand start handler pc %d --> %d\n",
	   current_pc, range->end_pc);
#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
  range->expanded = 1;
  expand_eh_region_start ();
}

tree
prepare_eh_table_type (type)
    tree type;
{
  tree exp;

  /* The "type" (metch_info) in a (Java) exception table is one:
   * a) NULL - meaning match any type in a try-finally.
   * b) a pointer to a (ccmpiled) class (low-order bit 0).
   * c) a pointer to the Utf8Const name of the class, plus one
   * (which yields a value with low-order bit 1). */

  if (type == NULL_TREE)
    exp = NULL_TREE;
  else if (is_compiled_class (type))
    exp = build_class_ref (type);
  else
    exp = fold (build 
		(PLUS_EXPR, ptr_type_node,
		 build_utf8_ref (build_internal_class_name (type)),
		 size_one_node));
  return exp;
}


/* Build a reference to the jthrowable object being carried in the
   exception header.  */

tree
build_exception_object_ref (type)
     tree type;
{
  tree obj;

  /* Java only passes object via pointer and doesn't require adjusting.
     The java object is immediately before the generic exception header.  */
  obj = build (EXC_PTR_EXPR, build_pointer_type (type));
  obj = build (MINUS_EXPR, TREE_TYPE (obj), obj,
	       TYPE_SIZE_UNIT (TREE_TYPE (obj)));
  obj = build1 (INDIRECT_REF, type, obj);

  return obj;
}

/* If there are any handlers for this range, isssue end of range,
   and then all handler blocks */
static void
expand_end_java_handler (range)
     struct eh_range *range;
{  
  tree handler = range->handlers;
  force_poplevels (range->start_pc);
  expand_start_all_catch ();
  for ( ; handler != NULL_TREE; handler = TREE_CHAIN (handler))
    {
      expand_start_catch (TREE_PURPOSE (handler));
      expand_goto (TREE_VALUE (handler));
      expand_end_catch ();
    }
  expand_end_all_catch ();
#if defined(DEBUG_JAVA_BINDING_LEVELS)
  indent ();
  fprintf (stderr, "expand end handler pc %d <-- %d\n",
	   current_pc, range->start_pc);
#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
}

/* Recursive helper routine for maybe_start_handlers. */

static void
check_start_handlers (range, pc)
     struct eh_range *range;
     int pc;
{
  if (range != NULL_EH_RANGE && range->start_pc == pc)
    {
      check_start_handlers (range->outer, pc);
      if (!range->expanded)
	expand_start_java_handler (range);
    }
}


static struct eh_range *current_range;

/* Emit any start-of-try-range starting at start_pc and ending after
   end_pc. */

void
maybe_start_try (start_pc, end_pc)
     int start_pc;
     int end_pc;
{
  struct eh_range *range;
  if (! doing_eh (1))
    return;

  range = find_handler (start_pc);
  while (range != NULL_EH_RANGE && range->start_pc == start_pc
	 && range->end_pc < end_pc)
    range = range->outer;
	 
  current_range = range;
  check_start_handlers (range, start_pc);
}

/* Emit any end-of-try-range ending at end_pc and starting before
   start_pc. */

void
maybe_end_try (start_pc, end_pc)
     int start_pc;
     int end_pc;
{
  if (! doing_eh (1))
    return;

  while (current_range != NULL_EH_RANGE && current_range->end_pc <= end_pc
	 && current_range->start_pc >= start_pc)
    {
      expand_end_java_handler (current_range);
      current_range = current_range->outer;
    }
}
