/* Glue to interface gcj with bytecode verifier.
   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010
   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 3, 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 COPYING3.  If not see
<http://www.gnu.org/licenses/>.

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 "tree.h"
#include "parse.h"

#include "verify.h"
#include "java-tree.h"
#include "java-except.h"
#include "diagnostic-core.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_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;
  gcc_assert (vfy_is_primitive (klass));
  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;
  gcc_assert (vfy_is_array (klass));
  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_class_type (void)
{
  return class_type_node;
}

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 = DECL_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 val = make_tree_vec (method->max_locals + depth);
  VEC_replace (tree, type_states, pc, val);
  /* Called for side effects.  */
  lookup_label (pc);
}

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

  if (type == object_type_node)
    type = object_ptr_type_node;

  vec = VEC_index (tree, type_states, pc);
  TREE_VEC_ELT (vec, slot) = type;
  /* Called for side effects.  */
  lookup_label (pc);
}

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

  vec = VEC_index (tree, type_states, pc);
  TREE_VEC_ELT (vec, slot) = type;
  /* Called for side effects.  */
  lookup_label (pc);
}

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;
}
