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

This file is part of GCC.

GCC 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.

GCC 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 GCC; 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 "coretypes.h"
#include "tm.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 (struct eh_range *);
static struct eh_range *find_handler_in_range (int, struct eh_range *,
					       struct eh_range *);
static void check_start_handlers (struct eh_range *, int);
static void free_eh_ranges (struct eh_range *range);

struct eh_range *current_method_handlers;

struct eh_range *current_try_block = 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;

/* Check the invariants of the structure we're using to contain
   exception regions.  Either returns true or fails an assertion
   check.  */

bool
sanity_check_exception_range (struct eh_range *range)
{
  struct eh_range *ptr = range->first_child;
  for (; ptr; ptr = ptr->next_sibling)
    {
      gcc_assert (ptr->outer == range
		  && ptr->end_pc > ptr->start_pc);
      if (ptr->next_sibling)
	gcc_assert (ptr->next_sibling->start_pc >= ptr->end_pc);
      gcc_assert (ptr->start_pc >= ptr->outer->start_pc
		  && ptr->end_pc <=  ptr->outer->end_pc);
      (void) sanity_check_exception_range (ptr);
    }

  return true;
}

#if defined(DEBUG_JAVA_BINDING_LEVELS)
extern int is_class_level;
extern int current_pc;
extern int binding_depth;
extern void indent (void);
static void
print_ranges (struct eh_range *range)
{
  if (! range)
    return;

  struct eh_range *child = range->first_child;
  
  indent ();
  fprintf (stderr, "handler pc %d --> %d ", range->start_pc, range->end_pc);
  
  tree handler = range->handlers;
  for ( ; handler != NULL_TREE; handler = TREE_CHAIN (handler))
    {
      tree type = TREE_PURPOSE (handler);
      if (type == NULL)
	type = throwable_type_node;
      fprintf (stderr, " type=%s ", IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
    }
  fprintf (stderr, "\n");

  int saved = binding_depth;
  binding_depth++;
  print_ranges (child);
  binding_depth = saved;

  print_ranges (range->next_sibling);
}
#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 (int pc, struct eh_range *range, 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 (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);
}

static void
free_eh_ranges (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 (void)
{
  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;
}

/* Split an exception range into two at PC.  The sub-ranges that
   belong to the range are split and distributed between the two new
   ranges.  */

static void
split_range (struct eh_range *range, int pc)
{
  struct eh_range *ptr;
  struct eh_range **first_child, **second_child;
  struct eh_range *h;

  /* First, split all the sub-ranges.  */
  for (ptr = range->first_child; ptr; ptr = ptr->next_sibling)
    {
      if (pc > ptr->start_pc
	  && pc < ptr->end_pc)
	{
	  split_range (ptr, pc);
	}
    }

  /* Create a new range.  */
  h = xmalloc (sizeof (struct eh_range));

  h->start_pc = pc;
  h->end_pc = range->end_pc;
  h->next_sibling = range->next_sibling;
  range->next_sibling = h;
  range->end_pc = pc;
  h->handlers = build_tree_list (TREE_PURPOSE (range->handlers),
				 TREE_VALUE (range->handlers));
  h->next_sibling = NULL;
  h->expanded = 0;
  h->stmt = NULL;
  h->outer = range->outer;
  h->first_child = NULL;

  ptr = range->first_child;
  first_child = &range->first_child;
  second_child = &h->first_child;

  /* Distribute the sub-ranges bewteen the two new ranges.  */
  for (ptr = range->first_child; ptr; ptr = ptr->next_sibling)
    {
      if (ptr->start_pc < pc)
	{
	  *first_child = ptr;
	  ptr->outer = range;
	  first_child = &ptr->next_sibling;
	}
      else
	{
	  *second_child = ptr;
	  ptr->outer = h;
	  second_child = &ptr->next_sibling;
	}
    }
  *first_child = NULL;
  *second_child = NULL;
}  


/* Add an exception range. 

   There are some missed optimization opportunities here.  For
   example, some bytecode obfuscators generate seemingly
   nonoverlapping exception ranges which, when coalesced, do in fact
   nest correctly.  We could merge these, but we'd have to fix up all
   the enclosed regions first and perhaps create a new range anyway if
   it overlapped existing ranges.
   
   Also, we don't attempt to detect the case where two previously
   added disjoint ranges could be coalesced by a new range.  */

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

  /* First, split all the existing ranges that we need to enclose.  */
  for (ptr = whole_range.first_child; ptr; ptr = ptr->next_sibling)
    {
      if (start_pc > ptr->start_pc
	  && start_pc < ptr->end_pc)
	{
	  split_range (ptr, start_pc);
	}

      if (end_pc > ptr->start_pc
	  && end_pc < ptr->end_pc)
	{
	  split_range (ptr, end_pc);
	}

      if (ptr->start_pc >= end_pc)
	break;
    }

  /* Create the new range.  */
  h = xmalloc (sizeof (struct eh_range));
  first_child = &h->first_child;

  h->start_pc = start_pc;
  h->end_pc = end_pc;
  h->first_child = NULL;
  h->outer = NULL_EH_RANGE;
  h->handlers = build_tree_list (type, handler);
  h->next_sibling = NULL;
  h->expanded = 0;
  h->stmt = NULL;

  /* Find every range at the top level that will be a sub-range of the
     range we're inserting and make it so.  */
  {
    struct eh_range **prev = &whole_range.first_child;
    for (ptr = *prev; ptr;)
      {
	struct eh_range *next = ptr->next_sibling;

	if (ptr->start_pc >= end_pc)
	  break;

	if (ptr->start_pc < start_pc)
	  {
	    prev = &ptr->next_sibling;
	  }
	else if (ptr->start_pc >= start_pc
		 && ptr->start_pc < end_pc)
	  {
	    *prev = next;
	    *first_child = ptr;
	    first_child = &ptr->next_sibling;
	    ptr->outer = h;
	    ptr->next_sibling = NULL;	  
	  }

	ptr = next;
      }
  }

  /* Find the right place to insert the new range.  */
  prev = &whole_range.first_child;
  for (ptr = *prev; ptr; prev = &ptr->next_sibling, ptr = ptr->next_sibling)
    {
      gcc_assert (ptr->outer == NULL_EH_RANGE);
      if (ptr->start_pc >= start_pc)
	break;
    }

  /* And insert it there.  */
  *prev = h;
  if (ptr)
    {
      h->next_sibling = ptr;
      h->outer = ptr->outer;
    }
}
      
  
/* if there are any handlers for this range, issue start of region */
static void
expand_start_java_handler (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) */
  pushlevel (0);
  register_exception_range (range,  range->start_pc, range->end_pc);
  range->expanded = 1;
}

tree
prepare_eh_table_type (tree type)
{
  tree exp;
  tree *slot;
  const char *name;
  char *buf;
  tree decl;
  tree utf8_ref;

  /* The "type" (match_info) in a (Java) exception table is a pointer to:
   * a) NULL - meaning match any type in a try-finally.
   * b) a pointer to a pointer to a class.
   * c) a pointer to a pointer to a utf8_ref.  The pointer is
   * rewritten to point to the appropriate class.  */

  if (type == NULL_TREE)
    return NULL_TREE;

  if (TYPE_TO_RUNTIME_MAP (output_class) == NULL)
    TYPE_TO_RUNTIME_MAP (output_class) = java_treetreehash_create (10, 1);
  
  slot = java_treetreehash_new (TYPE_TO_RUNTIME_MAP (output_class), type);
  if (*slot != NULL)
    return TREE_VALUE (*slot);

  if (is_compiled_class (type) && !flag_indirect_dispatch)
    {
      name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
      buf = alloca (strlen (name) + 5);
      sprintf (buf, "%s_ref", name);
      decl = build_decl (VAR_DECL, get_identifier (buf), ptr_type_node);
      TREE_STATIC (decl) = 1;
      DECL_ARTIFICIAL (decl) = 1;
      DECL_IGNORED_P (decl) = 1;
      TREE_READONLY (decl) = 1;
      TREE_THIS_VOLATILE (decl) = 0;
      DECL_INITIAL (decl) = build_class_ref (type);
      layout_decl (decl, 0);
      pushdecl (decl);
      exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (decl)), decl);
    }
  else
    {
      utf8_ref = build_utf8_ref (DECL_NAME (TYPE_NAME (type)));
      name = IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (utf8_ref, 0)));
      buf = alloca (strlen (name) + 5);
      sprintf (buf, "%s_ref", name);
      decl = build_decl (VAR_DECL, get_identifier (buf), utf8const_ptr_type);
      TREE_STATIC (decl) = 1;
      DECL_ARTIFICIAL (decl) = 1;
      DECL_IGNORED_P (decl) = 1;
      TREE_READONLY (decl) = 1;
      TREE_THIS_VOLATILE (decl) = 0;
      layout_decl (decl, 0);
      pushdecl (decl);
      exp = build1 (ADDR_EXPR, build_pointer_type (utf8const_ptr_type), decl);
      TYPE_CATCH_CLASSES (output_class) = 
	tree_cons (NULL, make_catch_class_record (exp, utf8_ref), 
		   TYPE_CATCH_CLASSES (output_class));
    }

  exp = convert (ptr_type_node, exp);

  *slot = tree_cons (type, exp, NULL_TREE);

  return exp;
}

static int
expand_catch_class (void **entry, void *x ATTRIBUTE_UNUSED)
{
  struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
  tree addr = TREE_VALUE ((tree)ite->value);
  tree decl;
  STRIP_NOPS (addr);
  decl = TREE_OPERAND (addr, 0);
  rest_of_decl_compilation (decl, global_bindings_p (), 0);
  return true;
}
  
/* For every class in the TYPE_TO_RUNTIME_MAP, expand the
   corresponding object that is used by the runtime type matcher.  */

void
java_expand_catch_classes (tree this_class)
{
  if (TYPE_TO_RUNTIME_MAP (this_class))
    htab_traverse 
      (TYPE_TO_RUNTIME_MAP (this_class),
       expand_catch_class, NULL);
}

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

tree
build_exception_object_ref (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 = build0 (EXC_PTR_EXPR, build_pointer_type (type));
  obj = build2 (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 */
void
expand_end_java_handler (struct eh_range *range)
{  
  tree handler = range->handlers;

  for ( ; handler != NULL_TREE; handler = TREE_CHAIN (handler))
    {
      /* For bytecode we treat exceptions a little unusually.  A
	 `finally' clause looks like an ordinary exception handler for
	 Throwable.  The reason for this is that the bytecode has
	 already expanded the finally logic, and we would have to do
	 extra (and difficult) work to get this to look like a
	 gcc-style finally clause.  */
      tree type = TREE_PURPOSE (handler);
      if (type == NULL)
	type = throwable_type_node;
      type = prepare_eh_table_type (type);

      {
	tree catch_expr = build2 (CATCH_EXPR, void_type_node, type,
				  build1 (GOTO_EXPR, void_type_node,
					  TREE_VALUE (handler)));
	tree try_catch_expr = build2 (TRY_CATCH_EXPR, void_type_node,
				      *get_stmts (), catch_expr);	
	*get_stmts () = try_catch_expr;
      }
    }
#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 (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 (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);
}

