/* Glue to interface gcj with bytecode verifier.
   Copyright (C) 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.  */

/* Written by Tom Tromey <tromey@redhat.com>.  */

#include "config.h"

#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "errors.h"
#include "parse.h"

#include "verify.h"
#include "java-tree.h"
#include "java-except.h"

void *
vfy_alloc (size_t bytes)
{
  return xmalloc (bytes);
}

void
vfy_free (void *mem)
{
  free (mem);
}

bool
vfy_strings_equal (vfy_string one, vfy_string two)
{
  return one == two;
}

const char *
vfy_string_bytes (vfy_string str)
{
  return IDENTIFIER_POINTER (str);
}

int
vfy_string_length (vfy_string str)
{
  return IDENTIFIER_LENGTH (str);
}

vfy_string
vfy_init_name (void)
{
  return init_identifier_node;
}

vfy_string
vfy_clinit_name (void)
{
  return clinit_identifier_node;
}

static const char*
skip_one_type (const char* ptr)
{
  int ch = *ptr++;

  while (ch == '[')
    { 
      ch = *ptr++;
    }
  
  if (ch == 'L')
    {
      do { ch = *ptr++; } while (ch != ';');
    }

  return ptr;
}

int
vfy_count_arguments (vfy_string signature)
{
  const char *ptr = IDENTIFIER_POINTER (signature);
  int arg_count = 0;

  /* Skip '('.  */
  ptr++;

  /* Count args.  */
  while (*ptr != ')')
    {
      ptr = skip_one_type (ptr);
      arg_count += 1;
    }

  return arg_count;
}

vfy_string
vfy_get_string (const char *s, int len)
{
  return get_identifier_with_length (s, len);
}

vfy_string
vfy_get_signature (vfy_method *method)
{
  return method->signature;
}

vfy_string
vfy_get_method_name (vfy_method *method)
{
  return method->name;
}

bool
vfy_is_static (vfy_method *method)
{
  return METHOD_STATIC (method->method);
}

const unsigned char *
vfy_get_bytecode (vfy_method *method)
{
  return method->bytes;
}

vfy_exception *
vfy_get_exceptions (vfy_method *method)
{
  return method->exceptions;
}

void
vfy_get_exception (vfy_exception *exceptions, int index, int *handler,
		   int *start, int *end, int *handler_type)
{
  *handler = exceptions[index].handler;
  *start = exceptions[index].start;
  *end = exceptions[index].end;
  *handler_type = exceptions[index].type;
}

int
vfy_tag (vfy_constants *pool, int index)
{
  int result = JPOOL_TAG (pool, index);
  /* gcj will resolve constant pool entries other than string and
     class references.  The verifier doesn't care about the values, so
     we just strip off the resolved flag.  */
  if ((result & CONSTANT_ResolvedFlag) != 0
      && result != CONSTANT_ResolvedString
      && result != CONSTANT_ResolvedClass)
    result &= ~ CONSTANT_ResolvedFlag;
  return result;
}

void
vfy_load_indexes (vfy_constants *pool, int index,
		  vfy_uint_16 *index0, vfy_uint_16 *index1)
{
  *index0 = JPOOL_USHORT1 (pool, index);
  *index1 = JPOOL_USHORT2 (pool, index);
}

vfy_constants *
vfy_get_constants (vfy_jclass klass)
{
  return TYPE_JCF (klass);
}

int
vfy_get_constants_size (vfy_jclass klass)
{
  return JPOOL_SIZE (TYPE_JCF (klass));
}

vfy_string
vfy_get_pool_string (vfy_constants *pool, int index)
{
  return get_name_constant (pool, index);
}

vfy_jclass
vfy_get_pool_class (vfy_constants *pool, int index)
{
  vfy_jclass k;
  k = get_class_constant (pool, index);
  return k;
}

vfy_string
vfy_make_string (const char *s, int len)
{
  tree result;
  char *s2 = (char *) s;
  char save = s2[len];
  s2[len] = '\0';
  result = get_identifier (s2);
  s2[len] = save;
  return result;  
}

vfy_string
vfy_get_class_name (vfy_jclass klass)
{
  return DECL_NAME (TYPE_NAME (klass));
}

bool
vfy_is_assignable_from (vfy_jclass target, vfy_jclass source)
{
  /* Any class is always assignable to itself, or java.lang.Object. */
  if (source == target || target == object_type_node)
    return true;

  /* For the C++ ABI, perform this test statically. */
  if (! flag_indirect_dispatch)
    return can_widen_reference_to (source, target);

  /* For the BC-ABI, we assume at compile time that reference types are always 
  compatible.  However, a type assertion table entry is emitted so that the
  runtime can detect binary-incompatible changes.  */

  add_type_assertion (current_class, JV_ASSERT_TYPES_COMPATIBLE, source,
		      target);
  return true;
}

char
vfy_get_primitive_char (vfy_jclass klass)
{
  tree sig;
  if (! vfy_is_primitive (klass))
    abort ();
  sig = build_java_signature (klass);
  return (IDENTIFIER_POINTER (sig))[0];
}

bool
vfy_is_array (vfy_jclass klass)
{
  return TYPE_ARRAY_P (klass);
}

bool
vfy_is_interface (vfy_jclass klass)
{
  return CLASS_INTERFACE (TYPE_NAME (klass));
}

bool
vfy_is_primitive (vfy_jclass klass)
{
  return JPRIMITIVE_TYPE_P (klass);
}

vfy_jclass
vfy_get_superclass (vfy_jclass klass)
{
  vfy_jclass k;
  k = CLASSTYPE_SUPER (klass);
  return k;
}

vfy_jclass
vfy_get_array_class (vfy_jclass klass)
{
  vfy_jclass k;
  k = build_java_array_type (klass, -1);
  return k;
}

vfy_jclass
vfy_get_component_type (vfy_jclass klass)
{
  vfy_jclass k;
  if (! vfy_is_array (klass))
    abort ();
  k = TYPE_ARRAY_ELEMENT (klass);
  if (TREE_CODE (k) == POINTER_TYPE)
    k = TREE_TYPE (k);
  return k;
}

bool
vfy_is_abstract (vfy_jclass klass)
{
  return CLASS_ABSTRACT (TYPE_NAME (klass));
}

vfy_jclass
vfy_find_class (vfy_jclass ignore ATTRIBUTE_UNUSED, vfy_string name)
{
  vfy_jclass k;

  k = get_type_from_signature (name);
  if (TREE_CODE (k) == POINTER_TYPE)
    k = TREE_TYPE (k);

  return k;
}

vfy_jclass
vfy_object_type (void)
{
  vfy_jclass k;
  k = object_type_node;
  return k;
}

vfy_jclass
vfy_string_type (void)
{
  vfy_jclass k;
  k = string_type_node;
  return k;
}

vfy_jclass
vfy_throwable_type (void)
{
  vfy_jclass k;
  k = throwable_type_node;
  return k;
}

vfy_jclass
vfy_unsuitable_type (void)
{
  return TYPE_SECOND;
}

vfy_jclass
vfy_return_address_type (void)
{
  return TYPE_RETURN_ADDR;
}

vfy_jclass
vfy_null_type (void)
{
  return TYPE_NULL;
}

bool
vfy_class_has_field (vfy_jclass klass, vfy_string name,
		     vfy_string signature)
{
  tree field = TYPE_FIELDS (klass);
  while (field != NULL_TREE)
    {
      if (DECL_NAME (field) == name
	  && build_java_signature (TREE_TYPE (field)) == signature)
	return true;
      field = TREE_CHAIN (field);
    }
  return false;
}

int
vfy_fail (const char *message, int pc, vfy_jclass ignore1 ATTRIBUTE_UNUSED,
	  vfy_method *ignore2 ATTRIBUTE_UNUSED)
{
  if (pc == -1)
    error ("verification failed: %s", message);
  else
    error ("verification failed at PC=%d: %s", pc, message);
  /* We have to return a value for the verifier to throw.  */
  return 1;
}

vfy_jclass
vfy_get_primitive_type (int type)
{
  vfy_jclass k;
  k = decode_newarray_type (type);
  return k;
}

void
vfy_note_stack_depth (vfy_method *method, int pc, int depth)
{
  tree label = lookup_label (pc);
  LABEL_TYPE_STATE (label) = make_tree_vec (method->max_locals + depth);
}

void
vfy_note_stack_type (vfy_method *method, int pc, int slot, vfy_jclass type)
{
  tree label, vec;
  
  slot += method->max_locals;

  if (type == object_type_node)
    type = object_ptr_type_node;

  label = lookup_label (pc);
  vec = LABEL_TYPE_STATE (label);
  TREE_VEC_ELT (vec, slot) = type;
}

void
vfy_note_local_type (vfy_method *method ATTRIBUTE_UNUSED, int pc, int slot,
		     vfy_jclass type)
{
  tree label, vec;
  
  if (type == object_type_node)
    type = object_ptr_type_node;

  label = lookup_label (pc);
  vec = LABEL_TYPE_STATE (label);
  TREE_VEC_ELT (vec, slot) = type;
}

void
vfy_note_instruction_seen (int pc)
{
  instruction_bits[pc] |= BCODE_VERIFIED;
}

/* Verify the bytecodes of the current method.
   Return 1 on success, 0 on failure. */
int
verify_jvm_instructions_new (JCF *jcf, const unsigned char *byte_ops,
			 long length)
{
  vfy_method method;
  int i, result, eh_count;
  vfy_exception *exceptions;

  method_init_exceptions ();

  JCF_SEEK (jcf, DECL_CODE_OFFSET (current_function_decl) + length);
  eh_count = JCF_readu2 (jcf);

  exceptions = (vfy_exception *) xmalloc (eh_count * sizeof (vfy_exception));
  for (i = 0; i < eh_count; ++i)
    {
      int start_pc, end_pc, handler_pc, catch_type;
      unsigned char *p = jcf->read_ptr + 8 * i;
      start_pc = GET_u2 (p);
      end_pc = GET_u2 (p+2);
      handler_pc = GET_u2 (p+4);
      catch_type = GET_u2 (p+6);

      if (start_pc < 0 || start_pc >= length
	  || end_pc < 0 || end_pc > length || start_pc >= end_pc
	  || handler_pc < 0 || handler_pc >= length)
	{
	  error ("bad pc in exception_table");
	  free (exceptions);
	  return 0;
	}

      exceptions[i].handler = handler_pc;
      exceptions[i].start = start_pc;
      exceptions[i].end = end_pc;
      exceptions[i].type = catch_type;

      add_handler (start_pc, end_pc,
		   lookup_label (handler_pc),
		   catch_type == 0 ? NULL_TREE
		   : get_class_constant (jcf, catch_type));
      instruction_bits[handler_pc] |= BCODE_EXCEPTION_TARGET;
    }

  gcc_assert (sanity_check_exception_range (&whole_range));

  method.method = current_function_decl;
  method.signature = build_java_signature (TREE_TYPE (current_function_decl));
  method.name = DECL_NAME (current_function_decl);
  method.bytes = byte_ops;
  method.exceptions = exceptions;
  method.defining_class = DECL_CONTEXT (current_function_decl);
  method.max_stack = DECL_MAX_STACK (current_function_decl);
  method.max_locals = DECL_MAX_LOCALS (current_function_decl);
  method.code_length = length;
  method.exc_count = eh_count;

  result = verify_method (&method);

  free (exceptions);

  return result;
}
