/* Glue to interface gcj with bytecode verifier.
   Copyright (C) 2003-2014 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 "stringpool.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);
  (*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 = (*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 = (*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;
}
