This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[BC ABI] gcj-abi-2-dev-branch created


2004-04-16  Andrew Haley  <aph@redhat.com>

	* verify.c (check_pending_block): Disable subroutine checks.
	(defer_merging): New function.
	(merge_types): If types are dummy, use defer_merging to combine them.
	(verify_jvm_instructions): If invocation is invokeinterface and
	target is dummy, assume target really is an interface.

	* parse.y (patch_invoke): Break out call to java_create_object.

	* lang.c (flag_verify_invocations): New.

	* jcf-parse.c (load_class): If we've already failed to load a
	class, don't try again.
	(load_class): If we can't find a .class file, don't fail, but emit
	a warning.
	(parse_class_file): Don't act on dummy methods.

	* java-tree.h (flag_verify_invocations): New.
	(TYPE_DUMMY): New.
	(lang_type.dummy_class): New field.
	(java_create_object): New function.
	(METHOD_DUMMY): New.

	* expr.c (build_field_ref): Widen field offset.
	(pop_type_0): If the type in stack_type_map is a TREE_LIST, check
	that each of its elements is compatible with the one we're
	popping.
	(pop_type_0): Issue a warning to say that we need to generate a
	runtime check.
	(java_create_object): New function.
	(build_field_ref): Only generate hard refs if we're not using
	indirect dispatch.
	(expand_java_field_op): If we're using !verify_invocations and we
	see a missing field, generate a decl for it.

	(expand_invoke): If a class doesn't have the method we seek and
	we're using !flag_verify_invocations, generate a decl for the
	method now.

	(build_known_method_ref): Always use indirect dispatch via the
	atable for static methods.

	(expand_java_NEW): Break out object creation into new function,	
	java_create_object.

	(can_widen_reference_to): Issue a warning to say that we need to
	generate a runtime check.

	* class.c (set_super_info): Inherit TYPE_DUMMY from sureclass.
	(make_method_value): Also use index for interfaces.
	(make_class_data): Skip dummy field for inherited data.
	Don't build method array for dummy methods.
	Set size_in_byte to -1 when using inirect dispatch
	Don't build a hard class ref if we don't have a hard ref to our
	superclass, or if we're using inirect dispatch.
	Null out dispatch tables.

	(layout_class_method): Don't complain about non-static method
	overrides static method is method is artificial.

	(build_static_field_ref): Disable atable references to static
	fields for the time being.

	(layout_class_methods): Check for CLASS_INTERFACE as
	well as CLASS_ABSTRACT.

Index: gcc/java/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/class.c,v
retrieving revision 1.180
diff -p -2 -c -w -r1.180 class.c
*** gcc/java/class.c	20 Mar 2004 14:03:33 -0000	1.180
--- gcc/java/class.c	16 Apr 2004 12:29:43 -0000
*************** set_super_info (int access_flags, tree t
*** 486,489 ****
--- 486,493 ----
  	= super_binfo;
        CLASS_HAS_SUPER (this_class) = 1;
+       /* FIXME: This is wrong.  */
+       if (TYPE_LANG_SPECIFIC (this_class)
+ 	  && TYPE_LANG_SPECIFIC (super_class))
+ 	TYPE_DUMMY (this_class) = TYPE_DUMMY (super_class);
      }
  
*************** build_class_ref (tree type)
*** 963,967 ****
        if  (flag_indirect_dispatch
  	   && type != output_class
! 	   && type != CLASSTYPE_SUPER (output_class)
  	   && TREE_CODE (type) == RECORD_TYPE)
  	return build_indirect_class_ref (type);
--- 967,971 ----
        if  (flag_indirect_dispatch
  	   && type != output_class
! // 	   && type != CLASSTYPE_SUPER (output_class)
  	   && TREE_CODE (type) == RECORD_TYPE)
  	return build_indirect_class_ref (type);
*************** build_static_field_ref (tree fdecl)
*** 1081,1085 ****
      }
  
!   if (flag_indirect_dispatch)
      {
        tree table_index 
--- 1085,1092 ----
      }
  
!   /* FIXME: The gcj runtime is broken in that atable references to
!      static fields in interpreted classes aren't fixed up until too
!      late.  When this is fixed we can re-enable this code.  */
!   if (0 && flag_indirect_dispatch)
      {
        tree table_index 
*************** make_method_value (tree mdecl)
*** 1250,1254 ****
    int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED;
  
!   if (!flag_indirect_dispatch && DECL_VINDEX (mdecl) != NULL_TREE)
      index = DECL_VINDEX (mdecl);
    else
--- 1257,1263 ----
    int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED;
  
!   if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (mdecl)))
!       || (!flag_indirect_dispatch 
! 	  && DECL_VINDEX (mdecl) != NULL_TREE))
      index = DECL_VINDEX (mdecl);
    else
*************** make_class_data (tree type)
*** 1465,1469 ****
    /* Build Field array. */
    field = TYPE_FIELDS (type);
!   if (DECL_NAME (field) == NULL_TREE)
      field = TREE_CHAIN (field);  /* Skip dummy field for inherited data. */
    for ( ;  field != NULL_TREE;  field = TREE_CHAIN (field))
--- 1474,1480 ----
    /* Build Field array. */
    field = TYPE_FIELDS (type);
!   while (field && DECL_ARTIFICIAL (field))
!     field = TREE_CHAIN (field);  /* Skip dummy fields.  */
!   if (field && DECL_NAME (field) == NULL_TREE)
      field = TREE_CHAIN (field);  /* Skip dummy field for inherited data. */
    for ( ;  field != NULL_TREE;  field = TREE_CHAIN (field))
*************** make_class_data (tree type)
*** 1520,1523 ****
--- 1531,1539 ----
  	  && (flag_inline_functions || optimize))
  	continue;
+       /* Even if we have a decl, we don't necessaily have the code.
+ 	 This can happen if we inherit a method from a superclass for
+ 	 which we don't have a .class file.  */
+       if (METHOD_DUMMY (method))
+ 	continue;
        init = make_method_value (method);
        method_count++;
*************** make_class_data (tree type)
*** 1563,1570 ****
    if (super == NULL_TREE)
      super = null_pointer_node;
!   else if (/* FIXME: we should also test for (!
! 	      flag_indirect_dispatch) here, but libgcj can't cope with
! 	      a symbolic reference a superclass in the class data.  */
! 	   assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
  	   && assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (super)))))
      super = build_class_ref (super);
--- 1579,1584 ----
    if (super == NULL_TREE)
      super = null_pointer_node;
!   else if (! flag_indirect_dispatch
! 	   && assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
  	   && assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (super)))))
      super = build_class_ref (super);
*************** make_class_data (tree type)
*** 1662,1667 ****
  		    fields_decl == NULL_TREE ? null_pointer_node
  		    : build1 (ADDR_EXPR, field_ptr_type_node, fields_decl));
!   PUSH_FIELD_VALUE (cons, "size_in_bytes", size_in_bytes (type));
!   PUSH_FIELD_VALUE (cons, "field_count", build_int_2 (field_count, 0));
    PUSH_FIELD_VALUE (cons, "static_field_count",
  		    build_int_2 (static_field_count, 0));
--- 1676,1687 ----
  		    fields_decl == NULL_TREE ? null_pointer_node
  		    : build1 (ADDR_EXPR, field_ptr_type_node, fields_decl));
!   /* If we're using the binary compatibility ABI we don't know the
!      size until load time.  */
!   PUSH_FIELD_VALUE (cons, "size_in_bytes", 
! 		    (flag_indirect_dispatch 
! 		     ? integer_minus_one_node 
! 		     : size_in_bytes (type)));
!   PUSH_FIELD_VALUE (cons, "field_count", 
! 		    build_int_2 (field_count, 0));
    PUSH_FIELD_VALUE (cons, "static_field_count",
  		    build_int_2 (static_field_count, 0));
*************** make_class_data (tree type)
*** 1729,1732 ****
--- 1749,1756 ----
    
    rest_of_decl_compilation (decl, (char*) 0, 1, 0);
+   
+   TYPE_OTABLE_DECL (type) = NULL_TREE;
+   TYPE_ATABLE_DECL (type) = NULL_TREE;
+   TYPE_CTABLE_DECL (type) = NULL_TREE;
  }
  
*************** layout_class_method (tree this_class, tr
*** 2177,2181 ****
        tree super_method = lookup_argument_method (super_class, method_name,
  						  method_sig);
!       if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method))
  	{
  	  DECL_VINDEX (method_decl) = DECL_VINDEX (super_method);
--- 2201,2206 ----
        tree super_method = lookup_argument_method (super_class, method_name,
  						  method_sig);
!       if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method)
! 	  && ! DECL_ARTIFICIAL (super_method))
  	{
  	  DECL_VINDEX (method_decl) = DECL_VINDEX (super_method);
Index: gcc/java/except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/except.c,v
retrieving revision 1.42
diff -p -2 -c -w -r1.42 except.c
Index: gcc/java/expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/expr.c,v
retrieving revision 1.185
diff -p -2 -c -w -r1.185 expr.c
*** gcc/java/expr.c	30 Mar 2004 19:19:06 -0000	1.185
--- gcc/java/expr.c	16 Apr 2004 12:29:44 -0000
*************** pop_type_0 (tree type, char **messagep)
*** 314,317 ****
--- 314,332 ----
    if (type == NULL_TREE || t == type)
      return t;
+   if (TREE_CODE (t) == TREE_LIST)
+     {      
+       do
+ 	{
+ 	  tree tt = TREE_PURPOSE (t);
+ 	  if (! can_widen_reference_to (tt, type))
+ 	    {
+ 	      t = tt;
+ 	      goto fail;
+ 	    }
+ 	  t = TREE_CHAIN (t);
+ 	}
+       while (t);
+       return t;
+     }
    if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
        && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
*************** pop_type_0 (tree type, char **messagep)
*** 332,337 ****
--- 347,362 ----
      }
  
+   if (! flag_verify_invocations && flag_indirect_dispatch
+       && t == object_ptr_type_node)
+     {
+       if (type != ptr_type_node)
+ 	warning ("need to insert runtime check for %s", 
+ 		 xstrdup (lang_printable_name (type, 0)));
+       return type;
+     }
+ 
    /* lang_printable_name uses a static buffer, so we must save the result
       from calling it the first time.  */
+  fail:
    {
      char *temp = xstrdup (lang_printable_name (type, 0));
*************** can_widen_reference_to (tree source_type
*** 378,381 ****
--- 403,414 ----
    if (source_type == target_type)
      return 1;
+ 
+   if (TYPE_DUMMY (source_type) || TYPE_DUMMY (target_type))
+     {
+       warning ("assert: %s is assign compatible with %s", 
+ 	       xstrdup (lang_printable_name (target_type, 0)),
+ 	       xstrdup (lang_printable_name (source_type, 0)));
+       return 1;
+     }
    else
      {
*************** can_widen_reference_to (tree source_type
*** 411,414 ****
--- 444,454 ----
  	  int target_depth = class_depth (target_type);
  
+ 	  if (TYPE_DUMMY (source_type) || TYPE_DUMMY (target_type))
+ 	    {
+ 	      warning ("assert: %s is assign compatible with %s", 
+ 		       xstrdup (lang_printable_name (target_type, 0)),
+ 		       xstrdup (lang_printable_name (source_type, 0)));
+ 	      return 1;
+ 	    }
   	  /* class_depth can return a negative depth if an error occurred */
  	  if (source_depth < 0 || target_depth < 0)
*************** bool class_has_finalize_method (tree typ
*** 1139,1158 ****
  }
  
  static void
  expand_java_NEW (tree type)
  {
-   tree alloc_node;
- 
-   alloc_node = (class_has_finalize_method (type) ? alloc_object_node
- 		  				 : alloc_no_finalizer_node);
    if (! CLASS_LOADED_P (type))
      load_class (type, 1);
    safe_layout_class (type);
!   push_value (build (CALL_EXPR, promote_type (type),
! 		     build_address_of (alloc_node),
! 		     tree_cons (NULL_TREE, build_class_ref (type),
! 				build_tree_list (NULL_TREE,
! 						 size_in_bytes (type))),
! 		     NULL_TREE));
  }
  
--- 1179,1204 ----
  }
  
+ tree
+ java_create_object (tree type)
+ {
+   tree alloc_node = (class_has_finalize_method (type) 
+ 		     ? alloc_object_node
+ 		     : alloc_no_finalizer_node);
+   tree size = flag_indirect_dispatch ? integer_zero_node : size_in_bytes (type);
+   
+   return build (CALL_EXPR, promote_type (type),
+ 		build_address_of (alloc_node),
+ 		tree_cons (NULL_TREE, build_class_ref (type),
+ 			   build_tree_list (NULL_TREE, size)),
+ 		NULL_TREE);
+ }
+ 
  static void
  expand_java_NEW (tree type)
  {
    if (! CLASS_LOADED_P (type))
      load_class (type, 1);
    safe_layout_class (type);
!   push_value (java_create_object (type));
  }
  
*************** build_field_ref (tree self_value, tree s
*** 1512,1521 ****
        if (base_type != TREE_TYPE (self_value))
  	self_value = fold (build1 (NOP_EXPR, base_type, self_value));
!       if (flag_indirect_dispatch
! 	  && output_class != self_class)
! 	/* FIXME: output_class != self_class is not exactly the right
! 	   test.  What we really want to know is whether self_class is
! 	   in the same translation unit as output_class.  If it is,
! 	   we can make a direct reference.  */
  	{
  	  tree otable_index =
--- 1558,1568 ----
        if (base_type != TREE_TYPE (self_value))
  	self_value = fold (build1 (NOP_EXPR, base_type, self_value));
!       if (! flag_syntax_only
! 	  && (flag_indirect_dispatch
! 	      /* DECL_FIELD_OFFSET == 0 if we have no reference for
! 		 the field, perhaps because we couldn't find the class
! 		 in which the field is defined.  
! 		 FIXME: We should investigate this.  */
! 	      || DECL_FIELD_OFFSET (field_decl) == 0))
  	{
  	  tree otable_index =
*************** build_known_method_ref (tree method, tre
*** 1768,1773 ****
    if (is_compiled_class (self_type))
      {
!       if (!flag_indirect_dispatch
! 	  || (!TREE_PUBLIC (method) && DECL_CONTEXT (method)))
  	{
  	  make_decl_rtl (method, NULL);
--- 1815,1828 ----
    if (is_compiled_class (self_type))
      {
!       /* At one point I used 
! 
!       (!TREE_PUBLIC (method) && DECL_CONTEXT (method))) 
!       
!       here, meaning that we would make a direct call to methods that
!       are in the current compilation unit and not public.  That ought
!       to work, right?  Wrong.  Unfortunately, for some reason we still
!       generate a PLT jump for such methods, and they can end up being
!       resolved in some other library.  Sigh.  */
!       if (!flag_indirect_dispatch)
  	{
  	  make_decl_rtl (method, NULL);
*************** expand_invoke (int opcode, int method_re
*** 2029,2032 ****
--- 2084,2089 ----
    if (method == NULL_TREE)
      {
+       if (flag_verify_invocations || ! flag_indirect_dispatch)
+ 	{
  	  error ("class '%s' has no method named '%s' matching signature '%s'",
  		 self_name,
*************** expand_invoke (int opcode, int method_re
*** 2034,2039 ****
  	     IDENTIFIER_POINTER (method_signature));
      }
    /* Invoke static can't invoke static/abstract method */
!   else if (opcode == OPCODE_invokestatic)
      {
        if (!METHOD_STATIC (method))
--- 2091,2116 ----
  		 IDENTIFIER_POINTER (method_signature));
  	}
+       else
+ 	{
+ 	  int flags = ACC_PUBLIC;
+ 	  if (opcode == OPCODE_invokestatic)
+ 	    flags |= ACC_STATIC;
+ 	  if (opcode == OPCODE_invokeinterface)
+ 	    {
+ 	      flags |= ACC_INTERFACE;
+ 	      CLASS_INTERFACE (TYPE_NAME (self_type)) = 1;
+ 	    }
+ 	  method = add_method (self_type, flags, method_name, method_signature);
+ 	  DECL_ARTIFICIAL (method) = 1;
+ 	  METHOD_DUMMY (method) = 1;
+ 	  layout_class_method (self_type, NULL,
+ 			       method, NULL);
+ 	}
+     }
+ 
    /* Invoke static can't invoke static/abstract method */
!   if (method != NULL_TREE)
!     {
!       if (opcode == OPCODE_invokestatic)
  	{
  	  if (!METHOD_STATIC (method))
*************** expand_invoke (int opcode, int method_re
*** 2056,2059 ****
--- 2133,2137 ----
  	    }
  	}
+     }
  
    if (method == NULL_TREE)
*************** expand_java_field_op (int is_static, int
*** 2336,2340 ****
  			  COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool, 
  						     field_ref_index));
!   const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
    tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
    tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, 
--- 2414,2419 ----
  			COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool, 
  						   field_ref_index));
!   const char *self_name = 
!     IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
    tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
    tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, 
*************** expand_java_field_op (int is_static, int
*** 2344,2347 ****
--- 2423,2427 ----
    tree field_ref;
    int is_error = 0;
+   tree original_self_type = self_type;
    tree field_decl = lookup_field (&self_type, field_name);
    if (field_decl == error_mark_node)
*************** expand_java_field_op (int is_static, int
*** 2351,2357 ****
--- 2431,2451 ----
    else if (field_decl == NULL_TREE)
      {
+       if (! flag_verify_invocations)
+ 	{
+ 	  int flags = ACC_PUBLIC;
+ 	  if (is_static)
+ 	    flags |= ACC_STATIC;
+ 	  self_type = original_self_type;
+ 	  field_decl = add_field (original_self_type, field_name,
+ 				  field_type, flags); 
+ 	  DECL_ARTIFICIAL (field_decl) = 1;
+ 	  DECL_IGNORED_P (field_decl) = 1;
+ 	}
+       else
+ 	{      
  	  error ("missing field '%s' in '%s'",
  		 IDENTIFIER_POINTER (field_name), self_name);
  	  is_error = 1;
+       }
      }
    else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
Index: gcc/java/java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.197
diff -p -2 -c -w -r1.197 java-tree.h
*** gcc/java/java-tree.h	19 Mar 2004 23:10:55 -0000	1.197
--- gcc/java/java-tree.h	16 Apr 2004 12:29:45 -0000
*************** extern GTY(()) struct JCF * current_jcf;
*** 245,248 ****
--- 245,250 ----
  extern int always_initialize_class_p;
  
+ extern int flag_verify_invocations;
+ 
  typedef struct CPool constant_pool;
  
*************** struct lang_decl_func GTY(())
*** 990,993 ****
--- 992,996 ----
  				   internally but which shouldn't be
  				   written to the .class file.  */
+   unsigned int dummy:1;		
  };
  
*************** struct lang_decl GTY(())
*** 1048,1051 ****
--- 1051,1057 ----
  /* The decl of the synthetic method `class$' used to handle `.class'
     for non primitive types when compiling to bytecode. */
+ 
+ #define TYPE_DUMMY(T)		(TYPE_LANG_SPECIFIC(T)->dummy_class)
+ 
  #define TYPE_DOT_CLASS(T)        (TYPE_LANG_SPECIFIC (T)->dot_class)
  #define TYPE_PACKAGE_LIST(T)     (TYPE_LANG_SPECIFIC (T)->package_list)
*************** struct lang_type GTY(())
*** 1109,1112 ****
--- 1115,1119 ----
    unsigned strictfp:1;		/* `strictfp' class.  */
    unsigned assertions:1;	/* Any method uses `assert'.  */
+   unsigned dummy_class:1;		/* Not a real class, just a placeholder.  */
  };
  
*************** extern void load_type_state (tree);
*** 1272,1275 ****
--- 1279,1283 ----
  extern void add_interface (tree, tree);
  extern tree force_evaluation_order (tree);
+ extern tree java_create_object (tree);
  extern int verify_constant_pool (struct JCF *);
  extern void start_java_method (tree);
*************** extern void gen_indirect_dispatch_tables
*** 1353,1356 ****
--- 1361,1366 ----
  
  /* Access flags etc for a method (a FUNCTION_DECL): */
+ 
+ #define METHOD_DUMMY(DECL) (DECL_LANG_SPECIFIC (DECL)->u.f.dummy)
  
  #define METHOD_PUBLIC(DECL) DECL_LANG_FLAG_1 (FUNCTION_DECL_CHECK (DECL))
Index: gcc/java/jcf-parse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-parse.c,v
retrieving revision 1.158
diff -p -2 -c -w -r1.158 jcf-parse.c
*** gcc/java/jcf-parse.c	29 Feb 2004 14:09:58 -0000	1.158
--- gcc/java/jcf-parse.c	16 Apr 2004 12:29:45 -0000
*************** load_class (tree class_or_name, int verb
*** 567,570 ****
--- 567,575 ----
    int class_loaded;
  
+   /* We've already failed, don't try again.  */
+   if (TREE_CODE (class_or_name) == RECORD_TYPE
+       && TYPE_DUMMY (class_or_name))
+     return;
+ 
    /* class_or_name can be the name of the class we want to load */
    if (TREE_CODE (class_or_name) == IDENTIFIER_NODE)
*************** load_class (tree class_or_name, int verb
*** 601,607 ****
      }
  
!   if (!class_loaded && verbose)
      error ("cannot find file for class %s", IDENTIFIER_POINTER (saved));
  }
  
  /* Parse the .class file JCF. */
--- 606,634 ----
      }
  
!   if (!class_loaded)
!     {
!       if (flag_verify_invocations || ! flag_indirect_dispatch
! 	  || flag_emit_class_files)
! 	{
! 	  if (verbose)
  	    error ("cannot find file for class %s", IDENTIFIER_POINTER (saved));
  	}
+       else if (verbose)
+ 	{
+ 	  /* This is just a diagnostic during testing, not a real problem.  */
+ 	  warning("cannot find file for class %s", 
+ 		  IDENTIFIER_POINTER (saved));
+ 	  
+ 	  /* Fake it.  */
+ 	  if (TREE_CODE (class_or_name) == RECORD_TYPE)
+ 	    {
+ 	      set_super_info (0, class_or_name, object_type_node, 0);
+ 	      TYPE_DUMMY (class_or_name) = 1;
+ 	      /* We won't be able to output any debug info for this class.  */
+ 	      DECL_IGNORED_P (TYPE_NAME (class_or_name)) = 1;
+ 	    }
+ 	}
+     }
+ }
  
  /* Parse the .class file JCF. */
*************** parse_class_file (void)
*** 717,721 ****
        JCF *jcf = current_jcf;
  
!       if (METHOD_ABSTRACT (method))
  	continue;
  
--- 744,748 ----
        JCF *jcf = current_jcf;
  
!       if (METHOD_ABSTRACT (method) || METHOD_DUMMY (method))
  	continue;
  
Index: gcc/java/lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/lang.c,v
retrieving revision 1.151
diff -p -2 -c -w -r1.151 lang.c
*** gcc/java/lang.c	20 Mar 2004 14:03:34 -0000	1.151
--- gcc/java/lang.c	16 Apr 2004 12:29:45 -0000
*************** int flag_optimize_sci = 1;
*** 181,184 ****
--- 181,187 ----
  int flag_indirect_dispatch = 0;
  
+ /* Don't attempt to verify invocations.  */
+ int flag_verify_invocations = 0; 
+ 
  /* When zero, don't generate runtime array store checks. */
  int flag_store_check = 1;
*************** java_get_callee_fndecl (tree call_expr)
*** 1252,1255 ****
--- 1255,1262 ----
  
    HOST_WIDE_INT index;
+ 
+   /* FIXME: This is disabled because we end up passing calls through
+      the PLT, and we do NOT want to do that.  */
+   return NULL;
  
    if (TREE_CODE (call_expr) != CALL_EXPR)
Index: gcc/java/parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.474
diff -p -2 -c -w -r1.474 parse.y
*** gcc/java/parse.y	19 Mar 2004 23:10:55 -0000	1.474
--- gcc/java/parse.y	16 Apr 2004 12:29:50 -0000
*************** patch_invoke (tree patch, tree method, t
*** 10859,10872 ****
        if (!TYPE_SIZE (class))
  	safe_layout_class (class);
!       size = size_in_bytes (class);
!       alloc_node =
! 	(class_has_finalize_method (class) ? alloc_object_node
! 		  			   : alloc_no_finalizer_node);
!       new = build (CALL_EXPR, promote_type (class),
! 		   build_address_of (alloc_node),
! 		   tree_cons (NULL_TREE, build_class_ref (class),
! 			      build_tree_list (NULL_TREE,
! 					       size_in_bytes (class))),
! 		   NULL_TREE);
        saved_new = save_expr (new);
        c1 = build_tree_list (NULL_TREE, saved_new);
--- 10859,10863 ----
        if (!TYPE_SIZE (class))
  	safe_layout_class (class);
!       new = java_create_object (class);
        saved_new = save_expr (new);
        c1 = build_tree_list (NULL_TREE, saved_new);
Index: gcc/java/verify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/verify.c,v
retrieving revision 1.59
diff -p -2 -c -w -r1.59 verify.c
*** gcc/java/verify.c	20 Dec 2003 15:38:28 -0000	1.59
--- gcc/java/verify.c	16 Apr 2004 12:29:50 -0000
*************** check_pending_block (tree target_label)
*** 85,90 ****
    if (current_subr == NULL)
      {
!       if (LABEL_IN_SUBR (target_label))
! 	return "might transfer control into subroutine";
      }
    else
--- 85,90 ----
    if (current_subr == NULL)
      {
! /*       if (LABEL_IN_SUBR (target_label)) */
! /* 	return "might transfer control into subroutine"; */
      }
    else
*************** check_pending_block (tree target_label)
*** 92,97 ****
        if (LABEL_IN_SUBR (target_label))
  	{
! 	  if (LABEL_SUBR_START (target_label) != current_subr)
! 	    return "transfer out of subroutine";
  	}
        else if (! LABEL_VERIFIED (target_label))
--- 92,97 ----
        if (LABEL_IN_SUBR (target_label))
  	{
! /* 	  if (LABEL_SUBR_START (target_label) != current_subr) */
! /* 	    return "transfer out of subroutine"; */
  	}
        else if (! LABEL_VERIFIED (target_label))
*************** check_pending_block (tree target_label)
*** 100,105 ****
  	  LABEL_SUBR_START (target_label) = current_subr;
  	}
!       else
! 	return "transfer out of subroutine";
      }
    return NULL;
--- 100,105 ----
  	  LABEL_SUBR_START (target_label) = current_subr;
  	}
! /*       else */
! /* 	return "transfer out of subroutine"; */
      }
    return NULL;
*************** subroutine_nesting (tree label)
*** 122,125 ****
--- 122,177 ----
  }
  
+ static tree
+ defer_merging (tree type1, tree type2)
+ {
+   if (TYPE_DUMMY (type1) || TYPE_DUMMY (type2))
+     {
+       warning ("assert: cannot merge types %s and %s", 
+ 	       xstrdup (lang_printable_name (type1, 0)),
+ 	       xstrdup (lang_printable_name (type2, 0)));
+     }
+ 
+   return object_ptr_type_node;
+ 
+   if (TREE_CODE (type1) == POINTER_TYPE)
+     type1 = TREE_TYPE (type1);
+   if (TREE_CODE (type2) == POINTER_TYPE)
+     type2 = TREE_TYPE (type2);
+ 
+   if (TREE_CODE (type1) == RECORD_TYPE && TREE_CODE (type2) == RECORD_TYPE)
+     {
+       tree list = build_tree_list (type1, NULL_TREE);
+       list = tree_cons (type2, NULL_TREE, list);
+       return list;
+     }
+ 
+   if (TREE_CODE (type1) == TREE_LIST && TREE_CODE (type2) == TREE_LIST)
+     {
+       return chainon (copy_list (type1), copy_list (type2));
+     }
+ 
+   if (TREE_CODE (type1) == TREE_LIST && TREE_CODE (type2) == RECORD_TYPE)
+     {
+       tree tmp = type1;
+       do
+ 	{
+ 	  if (TREE_PURPOSE (tmp) == type2)
+ 	    return type1;
+ 	  tmp = TREE_CHAIN (tmp);
+ 	}
+       while (tmp);
+ 
+       return tree_cons (type2, NULL_TREE, copy_list (type1));
+     }
+ 
+   if (TREE_CODE (type2) == TREE_LIST && TREE_CODE (type1) == RECORD_TYPE)
+     {
+       return defer_merging (type2, type1);
+     }
+ 
+   abort ();
+ }
+ 
+ 
  /* Return the "merged" types of TYPE1 and TYPE2.
     If either is primitive, the other must match (after promotion to int).
*************** merge_types (tree type1, tree type2)
*** 135,138 ****
--- 187,194 ----
        || type1 == TYPE_RETURN_ADDR || type2 == TYPE_RETURN_ADDR)
      return TYPE_UNKNOWN;  
+ 
+   if (TREE_CODE (type1) == TREE_LIST || TREE_CODE (type2) == TREE_LIST)
+     return defer_merging (type1, type2);
+ 
    if (TREE_CODE (type1) == POINTER_TYPE && TREE_CODE (type2) == POINTER_TYPE)
      {
*************** merge_types (tree type1, tree type2)
*** 149,152 ****
--- 205,211 ----
        tt2 = TREE_TYPE (type2);
  
+       if (TYPE_DUMMY (tt1) || TYPE_DUMMY (tt2))
+ 	return defer_merging (tt1, tt2);
+       
        /* If tt{1,2} haven't been properly loaded, now is a good time
           to do it. */
*************** verify_jvm_instructions (JCF* jcf, const
*** 651,654 ****
--- 710,715 ----
  	    ("invalid local variable index %d in load");
  	tmp = type_map[index];
+ 	if (TREE_CODE (tmp) != TREE_LIST)
+ 	  {
  	if (tmp == TYPE_UNKNOWN)
  	  VERIFICATION_ERROR_WITH_INDEX
*************** verify_jvm_instructions (JCF* jcf, const
*** 664,667 ****
--- 725,729 ----
  	  VERIFICATION_ERROR_WITH_INDEX
  	    ("loading local variable %d which has invalid type");
+ 	  }
  	PUSH_TYPE (tmp);
  	goto note_used;
*************** verify_jvm_instructions (JCF* jcf, const
*** 1024,1027 ****
--- 1086,1094 ----
  	    if (! CLASS_LOADED_P (self_type))
  	      load_class (self_type, 1);
+ 
+ 	    if (TYPE_DUMMY (self_type) && op_code == OPCODE_invokeinterface)
+ 	      /* Assume we are an interface.  */
+ 	      CLASS_INTERFACE (TYPE_NAME (self_type)) = 1;
+ 
  	    self_is_interface = CLASS_INTERFACE (TYPE_NAME (self_type));
  	    method_name = COMPONENT_REF_NAME (&current_jcf->cpool, index);
*************** verify_jvm_instructions (JCF* jcf, const
*** 1058,1061 ****
--- 1125,1129 ----
  		      VERIFICATION_ERROR 
  		        ("invalid argument number in invokeinterface");
+ 		  
  		  /* If we verify/resolve the constant pool, as we should,
  		     this test (and the one just following) are redundant.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]