public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Java: [BC] Verifier fixes and new -fnew-verifier option
@ 2004-10-18 22:06 Bryce McKinlay
  0 siblings, 0 replies; only message in thread
From: Bryce McKinlay @ 2004-10-18 22:06 UTC (permalink / raw)
  To: Java Patches, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 431 bytes --]

This patch adds a new argument, -fnew-verifier, to the Java front end 
which enables the new verifier. It also fixes several verifier thinkos 
and adds some missing initialization code. I'm checking this in to the 
BC branch.

The verifier now runs successfully for the small .class files I tried it 
on, but the compiler will still currently crash later on due to missing 
type maps that the old verifier was generating.

Bryce



[-- Attachment #2: java-verifier-3.patch --]
[-- Type: text/x-patch, Size: 9404 bytes --]

2004-10-15  Bryce McKinlay  <mckinlay@redhat.com>

	* expr.c (expand_bytecode): Use verify_jvm_instructions_new
	if flag_new_verifier is set.
	* java-tree.h (flag_new_verifier): Declare.
	* lang.opt (fnew-verifier): New option.
	* verify-impl.c: Work around namespace pollution by undef'ing 
	'current_class'.
	(struct verifier_context): Make 'bytecode' const.
	(verify_fail_pc): Pass -1 PC argument to vfy_fail.
	(types_compatible): For the BC-ABI, always consider reference types
	compatible.
	(check_class_constant): Use vfr->current_class.
	(check_constant): Likewise.
	(check_wide_constant): Likewise.
	(check_field_constant): Check for 'L' at start of type name.
	(get_one_type): Return pointer instead of type. Set type result in
	caller via passed type pointer.
	(compute_argument_types): Update to use new get_one_type arguments.
	(compute_return_type): Likewise.
	(make_verifier_context): New. Allocate and initialize 'vfr'.
	(free_verifier_context): New. Free 'vfr' and its contents.
	(verify_method): Remove ATTRIBUTE_UNUSED. Call make_verifier_context
	and free_verifier_context.

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/expr.c,v
retrieving revision 1.185.2.14
diff -u -r1.185.2.14 expr.c
--- expr.c	12 Oct 2004 12:42:43 -0000	1.185.2.14
+++ expr.c	18 Oct 2004 21:49:41 -0000
@@ -2872,8 +2872,16 @@
 	}
     }  
 
-  if (! verify_jvm_instructions (jcf, byte_ops, length))
-    return;
+  if (flag_new_verifier)
+    {
+      if (! verify_jvm_instructions_new (jcf, byte_ops, length))
+        return;
+    }
+  else
+    {
+      if (! verify_jvm_instructions (jcf, byte_ops, length))
+	return;
+    }
 
   /* Translate bytecodes.  */
   linenumber_pointer = linenumber_table;
Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.197.2.10
diff -u -r1.197.2.10 java-tree.h
--- java-tree.h	12 Oct 2004 12:42:46 -0000	1.197.2.10
+++ java-tree.h	18 Oct 2004 21:49:41 -0000
@@ -227,6 +227,9 @@
 /* When zero, don't generate runtime array store checks. */
 extern int flag_store_check;
 
+/* When nonzero, use the new bytecode verifier.  */
+extern int flag_new_verifier;
+
 /* Encoding used for source files.  */
 extern const char *current_encoding;
 
Index: lang.opt
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/lang.opt,v
retrieving revision 1.7.2.2
diff -u -r1.7.2.2 lang.opt
--- lang.opt	12 Oct 2004 12:42:51 -0000	1.7.2.2
+++ lang.opt	18 Oct 2004 21:49:41 -0000
@@ -175,5 +175,9 @@
 Java Var(flag_use_divide_subroutine) Init(1)
 Call a library routine to do integer divisions
 
+fnew-verifier
+Java Var(flag_new_verifier)
+Enable the new bytecode verifier
+
 version
 Java
Index: verify-impl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/verify-impl.c,v
retrieving revision 1.1.2.5
diff -u -r1.1.2.5 verify-impl.c
--- verify-impl.c	15 Oct 2004 17:23:19 -0000	1.1.2.5
+++ verify-impl.c	18 Oct 2004 21:49:42 -0000
@@ -15,6 +15,9 @@
 
 #include "verify.h"
 
+/* Hack to work around namespace pollution from java-tree.h.  */
+#undef current_class
+
 #ifdef VERIFY_DEBUG
 #include <stdio.h>
 #endif /* VERIFY_DEBUG */
@@ -193,7 +196,7 @@
   char *flags;
 
   /* The bytecode itself.  */
-  unsigned char *bytecode;
+  const unsigned char *bytecode;
   /* The exceptions.  */
   vfy_exception *exception;
 
@@ -238,8 +241,6 @@
 static void
 verify_fail_pc (const char *s, int pc)
 {
-  if (pc == -1)
-    pc = vfr->start_PC;
   vfy_fail (s, pc, vfr->current_class, vfr->current_method);  
 }
 
@@ -774,7 +775,13 @@
 	return false;
     }
 
-  return ref_compatible (t->klass, k->klass);
+  /* Reference types are always compatible for the BC-ABI. We defer this test
+  till runtime. 
+  FIXME: 1. type assertion generation
+         2. implement real test for old ABI ?? */
+
+  return true;
+  /* return ref_compatible (t->klass, k->klass); */
 }
 
 static bool
@@ -2101,7 +2108,7 @@
 {
   type t;
   check_pool_index (index);
-  vfy_constants *pool = vfy_get_constants (current_class);
+  vfy_constants *pool = vfy_get_constants (vfr->current_class);
   if (vfy_tag (pool, index) == JV_CONSTANT_ResolvedString
       || vfy_tag (pool, index) == JV_CONSTANT_String)
     init_type_from_class (&t, vfy_string_type ());
@@ -2119,7 +2126,7 @@
 {
   type t;
   check_pool_index (index);
-  vfy_constants *pool = vfy_get_constants (current_class);
+  vfy_constants *pool = vfy_get_constants (vfr->current_class);
   if (vfy_tag (pool, index) == JV_CONSTANT_Long)
     init_type_from_tag (&t, long_type);
   else if (vfy_tag (pool, index) == JV_CONSTANT_Double)
@@ -2136,7 +2143,7 @@
 			vfy_string *name, vfy_string *fmtype)
 {
   check_pool_index (index);
-  vfy_constants *pool = vfy_get_constants (current_class);
+  vfy_constants *pool = vfy_get_constants (vfr->current_class);
   if (vfy_tag (pool, index) != expected)
     verify_fail_pc ("didn't see expected constant", vfr->start_PC);
   /* Once we know we have a Fieldref or Methodref we assume that it
@@ -2169,7 +2176,7 @@
     *class_type = ct;
   typec = vfy_string_bytes (field_type);
   len = vfy_string_length (field_type);
-  if (typec[0] == '[' || typec[len - 1] == 'L')
+  if (typec[0] == '[' || typec[0] == 'L')
     init_type_from_string (&t, field_type);
   else
     init_type_from_tag (&t, get_type_val_for_signature (typec[0]));
@@ -2188,8 +2195,8 @@
 				 method_name, method_signature);
 }
 
-static type
-get_one_type (const char *p)
+static char *
+get_one_type (char *p, type *t)
 {
   const char *start = p;
 
@@ -2208,7 +2215,8 @@
 	++p;
       ++p;
       vfy_string name = vfy_get_string (start, p - start);
-      return make_type_from_string (name);
+      *t = make_type_from_string (name);
+      return p;
     }
 
   /* Casting to jchar here is ok since we are looking at an ASCII
@@ -2219,15 +2227,17 @@
     {
       /* Callers of this function eventually push their arguments on
          the stack.  So, promote them here.  */
-      type t = make_type (rt);
-      vfy_promote_type (&t);
-      return t;
+      type new_t = make_type (rt);
+      vfy_promote_type (&new_t);
+      *t = new_t;
+      return p;
     }
 
   vfy_jclass k = construct_primitive_array_type (rt);
   while (--arraycount > 0)
     k = vfy_get_array_class (k);
-  return make_type_from_class (k);
+  *t = make_type_from_class (k);
+  return p;
 }
 
 static void 
@@ -2240,17 +2250,19 @@
 
   int i = 0;
   while (*p != ')')
-    types[i++] = get_one_type (p);
+    p = get_one_type (p, &types[i++]);
 }
 
 static type
 compute_return_type (vfy_string signature)
 {
   char *p = (char *) vfy_string_bytes (signature);
+  type t;
   while (*p != ')')
     ++p;
   ++p;
-  return get_one_type (p);
+  get_one_type (p, &t);
+  return t;
 }
 
 static void
@@ -3335,9 +3347,17 @@
   debug_print ("--------------------------------\n");
   debug_print ("-- Verifying method `%s'\n", m->self->name->chars());
 
+}
+#endif
+
+static void
+make_verifier_context (vfy_method *m)
+{
+  vfr = (verifier_context *) vfy_alloc (sizeof (struct verifier_context));
+
   vfr->current_method = m;
-  bytecode = m->bytecode ();
-  exception = m->exceptions ();
+  vfr->bytecode = vfy_get_bytecode (m);
+  vfr->exception = vfy_get_exceptions (m);
   vfr->current_class = m->defining_class;
 
   vfr->states = NULL;
@@ -3346,53 +3366,64 @@
   vfr->isect_list = NULL;
 }
 
-~_Jv_BytecodeVerifier ()
+static void
+free_verifier_context (void)
 {
-  if (flags)
-    _Jv_Free (flags);
+  vfy_string_list *utf8_list;
+  ref_intersection *isect_list;
+
+  if (vfr->flags)
+    vfy_free (vfr->flags);
 
+  utf8_list = vfr->utf8_list;
   while (utf8_list != NULL)
     {
-      linked<_Jv_Utf8Const> *n = utf8_list->next;
-      _Jv_Free (utf8_list);
+      vfy_string_list *n = utf8_list->next;
+      vfy_free (utf8_list);
       utf8_list = n;
     }
 
+  isect_list = vfr->isect_list;
   while (isect_list != NULL)
     {
       ref_intersection *next = isect_list->alloc_next;
-      delete isect_list;
+      vfy_free (isect_list);
       isect_list = next;
     }
 
-  if (vfr->states)
+  if (vfr->states != NULL)
     {
-      for (int i = 0; i < vfr->current_method->code_length; ++i)
+      int i;
+      for (i = 0; i < vfr->current_method->code_length; ++i)
 	{
-	  linked<state *> *iter = vfr->states[i];
+	  state_list *iter = vfr->states[i];
 	  while (iter != NULL)
 	    {
-	      linked<state *> *next = iter->next;
-	      delete iter->val;
+	      state_list *next = iter->next;
+	      vfy_free (iter->val);
 	      vfy_free (iter);
 	      iter = next;
 	    }
 	}
-      vfy_free (states);
+      vfy_free (vfr->states);
     }
+  
+  vfy_free (vfr);
 }
 
-#endif
-
 int
-verify_method (vfy_method *meth ATTRIBUTE_UNUSED)
+verify_method (vfy_method *meth)
 {
-  /* static verifier initialization .. init type_int etc */
+  printf ("verify_method (%s) %i\n", vfy_string_bytes (meth->name),
+    meth->code_length);
+  
+  if (vfr != NULL)
+    verify_fail ("verifier re-entered");
 
-  /* push_verifier_context () */
-  /* _Jv_BytecodeVerifier v (meth); */
-  /* init_verifier_context () */
+  make_verifier_context (meth);
   verify_instructions ();
-  /* pop_verifier_context () */
+  free_verifier_context ();
+  vfr = NULL;
+
   return 0;
 }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2004-10-18 22:05 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-18 22:06 Java: [BC] Verifier fixes and new -fnew-verifier option Bryce McKinlay

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).