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]

[gcjx] Patch: FYI: first work on verifier merge


I'm checking this in on the gcjx branch.

This is the first work toward having a single 'verify.cc' in the tree.
This removes the uses of std::string from the gcjx verifier, and it
includes an initial (and completely untested) verify.h for libjava.

Tom

Index: libjava/ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* include/verify.h: New file.

Index: gcjx/ChangeLog
from  Tom Tromey  <tromey@redhat.com>
	* bytecode/verify.cc (verify_fail): Take 'char*' argument.
	(get_type_val_for_signature): Don't use std::string.
	(verify_dimensions): Likewise.
	(state::merge): Likewise.
	(state::state_mergeable_p): Likewise.
	(push_type): Likewise.
	(compute_jump): Likewise.
	(note_branch_target): Likewise.
	(skip_padding): Likewise.
	(branch_prepass): Likewise.
	(check_pool_index): Likewise.
	(verify_instructions_0): Likewise.
	* verify.h (vfy_get_interface_count): Removed.

Index: gcjx/verify.h
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/Attic/verify.h,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 verify.h
--- gcjx/verify.h 27 Mar 2005 02:38:14 -0000 1.1.2.2
+++ gcjx/verify.h 27 Mar 2005 02:42:25 -0000
@@ -242,11 +242,6 @@
   return iter == assert_cast<model_class *> (klass)->get_interfaces ().end ();
 }
 
-inline int vfy_get_interface_count (vfy_jclass klass)
-{
-  return assert_cast<model_class *> (klass)->get_interfaces ().size ();
-}
-
 inline vfy_jclass vfy_get_interface (vfy_jclass, vfy_iface_iterator &iter)
 {
   return (*iter)->type ();
Index: gcjx/bytecode/verify.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/verify.cc,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 verify.cc
--- gcjx/bytecode/verify.cc 27 Mar 2005 02:38:15 -0000 1.1.2.2
+++ gcjx/bytecode/verify.cc 27 Mar 2005 02:42:28 -0000
@@ -204,12 +204,11 @@
     return val;
   }
 
-  __attribute__ ((__noreturn__)) void verify_fail (const std::string &s,
-						   jint pc = -1)
+  __attribute__ ((__noreturn__)) void verify_fail (const char *s, jint pc = -1)
   {
     if (pc == -1)
       pc = start_PC;
-    vfy_fail (s.c_str (), pc, current_class, current_method);
+    vfy_fail (s, pc, current_class, current_method);
   }
 
   // This enum holds a list of tags for all the different types we
@@ -483,8 +482,11 @@
 	rt = void_type;
 	break;
       default:
-        verify_fail (std::string () +
-                     "invalid character '" + sig + "' in signature");
+	{
+	  char buf[50];
+	  sprintf (buf, "invalid character '%c' in signature", char (sig));
+	  verify_fail (buf);
+	}
       }
     return rt;
   }
@@ -857,9 +859,13 @@
         verifier->verify_fail ("internal error in type::verify_dimensions ()");
 
       if (klass->count_dimensions () < ndims)
-        verifier->verify_fail (std::string () + "array type has fewer "
-                               + "dimensions (" + klass->count_dimensions ()
-                               + ") than required (" + ndims + ")");
+	{
+	  char buf[100];
+	  sprintf (buf, "array type has fewer dimensions (%d) than "
+		   "required (%d)", klass->count_dimensions (),
+		   ndims);
+	  verifier->verify_fail (buf);
+	}
     }
 
     // Merge OLD_TYPE into this.  On error throw exception.  Return
@@ -1090,8 +1096,12 @@
 
       // Merge stacks.
       if (state_old->stacktop != stacktop)  // FIXME stackdepth instead?
-        verifier->verify_fail (std::string () + "stack sizes differ: "
-                               + state_old->stacktop + " and " + stacktop);
+	{
+	  char buf[30];
+	  sprintf (buf, "stack sizes differ: %d and %d", state_old->stacktop,
+		   stacktop);
+	  verifier->verify_fail (buf);
+	}
       for (int i = 0; i < state_old->stacktop; ++i)
 	{
 	  if (stack[i].merge (state_old->stack[i], false, verifier))
@@ -1144,8 +1154,12 @@
       // we've found two execution paths that reach a branch target
       // with different stack depths.  FIXME stackdepth instead?
       if (stacktop != other->stacktop)
-        verifier->verify_fail (std::string () + "stack sizes differ: "
-                               + stacktop + " and " + other->stacktop);
+	{
+	  char buf[50];
+	  sprintf (buf, "stack sizes differ: %d and %d", stacktop,
+		   other->stacktop);
+	  verifier->verify_fail (buf);
+	}
 
       for (int i = 0; i < stacktop; ++i)
 	if (! stack[i].state_mergeable_p (other->stack[i]))
@@ -1244,10 +1258,13 @@
 
     int depth = t.depth ();
     if (current_state->stackdepth + depth > current_method->max_stack)
-      verify_fail (std::string () + "stack overflow; "
-                   + "current depth=" +current_state->stackdepth + ", "
-                   + "max_stack=" + current_method->max_stack + ", "
-                   + "pushing " + depth);
+      {
+	char buf[100];
+	sprintf (buf, "stack overflow; current depth=%d, max_stack=%d, "
+		 "pushing %d", current_state->stackdepth,
+		 current_method->max_stack, depth);
+	verify_fail (buf);
+      }
     current_state->stack[current_state->stacktop++] = t;
     current_state->stackdepth += depth;
   }
@@ -1351,9 +1368,12 @@
   {
     int npc = start_PC + offset;
     if (npc < 0 || npc >= current_method->code_length)
-      verify_fail (std::string () + "branch out of range: "
-                   + "destination=" + npc + ", "
-                   + "code_length=" + current_method->code_length, start_PC);
+      {
+	char buf[100];
+	sprintf (buf, "branch out of range: destination=%d, code_length=%d",
+		 npc, current_method->code_length);
+	verify_fail (buf, start_PC);
+      }
     return npc;
   }
 
@@ -1473,9 +1493,11 @@
     // fetching the target and we haven't yet checked the next
     // instruction.
     if (pc < PC && ! (flags[pc] & FLAG_INSN_START))
-      verify_fail (std::string () + "branch to " + pc
-		   + " not to instruction start",
-		   start_PC);
+      {
+	char buf[30];
+	sprintf (buf, "branch to %d not to instruction start", pc);
+	verify_fail (buf, start_PC);
+      }
     flags[pc] |= FLAG_BRANCH_TARGET;
   }
 
@@ -1485,7 +1507,11 @@
       {
         jint b = get_byte ();
         if (b != 0)
-          verify_fail (std::string () + "found nonzero padding byte " + b);
+	  {
+	    char buf[30];
+	    sprintf (buf, "found nonzero padding byte %d", b);
+	    verify_fail (buf);
+	  }
       }
   }
 
@@ -1801,10 +1827,12 @@
 	      jint low = get_int ();
 	      jint high = get_int ();
 	      if (low > high)
-	        verify_fail (std::string ()
-	                     + "invalid tableswitch: low=" + low + ", "
-	                     + "high=" + high,
-	                     start_PC);
+		{
+		  char buf[50];
+		  sprintf (buf, "invalid tableswitch: low=%d, high=%d",
+			   low, high);
+		  verify_fail (buf, start_PC);
+		}
 	      for (int i = low; i <= high; ++i)
 		note_branch_target (compute_jump (get_int ()));
 	    }
@@ -1908,8 +1936,11 @@
   void check_pool_index (int index)
   {
     if (index < 0 || index >= vfy_get_constants_size (current_method))
-      verify_fail (std::string () + "constant pool index "
-		   + index + " out of range", start_PC);
+      {
+	char buf[50];
+	sprintf (buf, "constant pool index %d out of range", index);
+	verify_fail (buf, start_PC);
+      }
   }
 
   type check_class_constant (int index)
@@ -2846,10 +2877,12 @@
 		  nargs = get_byte ();
 		  jint dummy_byte = get_byte ();
 		  if (dummy_byte != 0)
-		    verify_fail (std::string ()
-				 + "invokeinterface dummy byte is "
-				 + dummy_byte
-		                 + " instead of 0");
+		    {
+		      char buf[50];
+		      sprintf (buf, "invokeinterface dummy byte is %d "
+			       "instead of 0", dummy_byte);
+		      verify_fail (buf);
+		    }
 		}
 
 	      bool is_init = false;
@@ -2905,9 +2938,14 @@
 
 	      vfy_jclass klass = class_type.klass->getclass (this);
 	      if (! vfy_has_method (klass, method_name, method_descriptor))
-		verify_fail (std::string () + "method '" + method_name + "' "
-		             + "with descriptor '" + method_descriptor + "' "
-		             + "not found");
+		{
+		  const char *mn = vfy_string_bytes (method_name);
+		  const char *md = vfy_string_bytes (method_descriptor);
+		  char buf[50 + strlen (mn) + strlen (md)];
+		  sprintf (buf, "method '%s' with descriptor '%s' not found",
+			   mn, md);
+		  verify_fail (buf);
+		}
 	    }
 	    break;
 
@@ -3015,9 +3053,12 @@
 	      type atype = check_class_constant (get_ushort ());
 	      int dim = get_byte ();
 	      if (dim < 1)
-	        verify_fail (std::string ()
-	                     + "too few dimensions to multianewarray: " + dim,
-	                     start_PC);
+		{
+		  char buf[50];
+		  sprintf (buf, "too few dimensions to multianewarray: %d",
+			   dim);
+		  verify_fail (buf, start_PC);
+		}
 	      atype.verify_dimensions (dim, this);
 	      for (int i = 0; i < dim; ++i)
 		pop_type (int_type);
Index: libjava/include/verify.h
===================================================================
RCS file: libjava/include/verify.h
diff -N libjava/include/verify.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libjava/include/verify.h 27 Mar 2005 02:42:32 -0000
@@ -0,0 +1,356 @@
+/* Declarations to interface libgcj with bytecode verifier.
+   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+gcjx is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+gcjx 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with gcjx; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc.,
+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.  */
+
+// This is glue between libjava and the verifier.
+
+#ifndef JV_VERIFY_H
+#define JV_VERIFY_H
+
+#include "java-cpool.h"
+#include "java/lang/Class.h"
+
+typedef _Jv_Constants *vfy_constants;
+
+typedef _Jv_Utf8Const *vfy_string;
+
+typedef jclass vfy_jclass;
+
+typedef jchar vfy_uint_16;
+
+typedef _Jv_InterpException vfy_exception;
+
+typedef _Jv_InterpMethod vfy_method;
+
+inline vfy_constants *vfy_get_constants (vfy_method *method)
+{
+  return &method->defining_class->constants;
+}
+
+inline void *vfy_alloc (size_t bytes)
+{
+  return _Jv_Malloc (bytes);
+}
+
+inline void vfy_free (void *mem)
+{
+  _Jv_Free (mem);
+}
+
+inline bool vfy_strings_equal (vfy_string one, vfy_string two)
+{
+  return _Jv_equalUtf8Consts (one, two);
+}
+
+inline const char *vfy_string_bytes (vfy_string str)
+{
+  return str->chars();
+}
+
+inline vfy_string vfy_init_name (void)
+{
+  return gcj::init_name;
+}
+
+inline vfy_string vfy_clinit_name (void)
+{
+  return gcj:clinit_name;
+}
+
+int vfy_count_arguments (vfy_string signature)
+{
+  return _Jv_count_arguments (signature, false);
+}
+
+inline vfy_string vfy_get_signature (vfy_method *method)
+{
+  return method->self->signature;
+}
+
+inline vfy_string vfy_get_method_name (vfy_method *method)
+{
+  return method->self->name;
+}
+
+inline bool vfy_is_static (vfy_method *method)
+{
+  return (method->self->accflags & ACC_STATIC) != 0;
+}
+
+inline const unsigned char *vfy_get_bytecode (vfy_method *method)
+{
+  return method->bytecode ();
+}
+
+inline vfy_exception *vfy_get_exceptions (vfy_method *method)
+{
+  return method->block->get_exceptions ();
+}
+
+inline void vfy_get_exception (vfy_exception *table, int index, int *handler,
+			       int *start, int *end, int *handler_type)
+{
+  *handler = table[index].handler_pc.i;
+  *start = table[index].start_pc.i;
+  *end = table[index].end_pc.i;
+  *handler_type = table[index].handler_type.i;
+}
+
+inline int vfy_tag (vfy_constants *pool, int index)
+{
+  return pool->tag[index];
+}
+
+inline void vfy_load_indexes (vfy_constants *pool, int index,
+			      vfy_uint_16 *index0, vfy_uint_16 *index1)
+{
+  _Jv_loadIndexes (pool->data, *index0, *index1);
+}
+
+inline int vfy_get_constants_size (vfy_method *method)
+{
+  return method->defining_class->constants.size;
+}
+
+inline vfy_string vfy_get_pool_string (vfy_constants *pool, int index)
+{
+  return pool->data[index].utf8;
+}
+
+inline vfy_jclass vfy_find_class (vfy_method *method, vfy_jclass context,
+				  vfy_string name)
+{
+  using namespace java::lang;
+  ClassLoader *loader = context->getClassLoaderInternal();
+  // We might see either kind of name.  Sigh.
+  vfy_jclass klass;
+  if (name->first() == 'L' && name->limit()[-1] == ';')
+    klass = _Jv_FindClassFromSignature (name->chars(), loader);
+  else
+    klass = Class::forName (_Jv_NewStringUtf8Const (name), false, loader);
+  return klass;
+}
+
+/**
+ * Tests whether class k has a method with a given name and descriptor. Most
+ * verifiers don't check this, so implementations are free to simply return
+ * true regardless, and report the problem later with a NoSuchMethodException
+ * at runtime or whatever. gjcx can use this to check the bytecode it emits.
+ */
+inline bool vfy_has_method (vfy_jclass k, vfy_string method_name,
+                            vfy_string method_descriptor)
+{
+  for (int i = 0; i < k->method_count; ++i)
+    {
+      if (_Jv_equalUtf8Consts (k->methods[i].name, method_name)
+	  && _Jv_equalUtf8Consts (k->methods[i].signature, method_descriptor))
+	return true;
+    }
+  return false;
+}
+
+inline vfy_jclass vfy_get_pool_resolved_class (vfy_method *method,
+					       vfy_constants *pool,
+					       int index)
+{
+  return vfy_find_class (method, method->declaring_class,
+			 pool->data[index].utf8);
+}
+
+inline vfy_string vfy_get_pool_class (vfy_method *method, vfy_constants *pool,
+				      int index)
+{
+  // FIXME: is pool linked at this point?
+  return pool->data[index].utf8;
+}
+
+// Return true if the class declares a field with the given name.  The
+// type of the field doesn't matter.
+inline bool vfy_class_has_field_p (vfy_jclass type, vfy_string name)
+{
+  for (int i = 0; i < type->field_count; ++i)
+    {
+      if (_Jv_equalUtf8Consts (type->fields[i].name, name))
+	return true;
+    }
+  return false;
+}
+
+inline vfy_string vfy_make_string (const char *s, int len)
+{
+  return _Jv_makeUtf8Const (s, len);
+}
+
+inline vfy_string vfy_get_class_name (vfy_jclass klass)
+{
+  return klass->name;
+}
+
+inline char vfy_get_primitive_char (vfy_jclass klass)
+{
+  return char (klass->method_count);
+}
+
+
+typedef int vfy_iface_iterator;
+
+inline vfy_iface_iterator vfy_iface_iterator_begin (vfy_jclass klass)
+{
+  return 0;
+}
+
+inline bool vfy_iface_iterator_done (vfy_jclass klass, vfy_iface_iterator iter)
+{
+  return iter == klass->interface_count;
+}
+
+inline vfy_jclass vfy_get_interface (vfy_jclass klass, vfy_iface_iterator iter)
+{
+  return klass->interface_count;
+}
+
+inline bool vfy_is_array (vfy_jclass klass)
+{
+  return klass->isArray ();
+}
+
+inline bool vfy_is_interface (vfy_jclass klass)
+{
+  return klass->isInterface ();
+}
+
+// FIXME: what to do for void?
+inline bool vfy_is_primitive (vfy_jclass klass)
+{
+  return klass->isPrimitive ();
+}
+
+inline vfy_jclass vfy_get_superclass (vfy_jclass klass)
+{
+  return klass->getSuperclass ();
+}
+
+inline vfy_jclass vfy_get_array_class (vfy_jclass klass)
+{
+  return _Jv_GetArrayClass (klass, klass->getClassLoaderInternal ());
+}
+
+inline vfy_jclass vfy_get_component_type (vfy_jclass klass)
+{
+  return klass->getComponentType ();
+}
+
+inline bool vfy_is_abstract (vfy_jclass klass)
+{
+  return (klass->getModifiers () & ACC_ABSTRACT) != 0;
+}
+
+inline vfy_jclass vfy_object_type (void)
+{
+  return &java::lang::Object::class$
+}
+
+inline vfy_jclass vfy_string_type (void)
+{
+  return &java::lang::String::class$
+}
+
+inline vfy_jclass vfy_throwable_type (void)
+{
+  return &java::lang::Throwable::class$
+}
+
+inline vfy_jclass vfy_class_type (void)
+{
+  return &java::lang::Class::class$
+}
+
+__attribute__ ((__noreturn__))
+inline int vfy_fail (const char *message, int pc, vfy_jclass,
+		     vfy_method *method)
+{
+  using namespace java::lang;
+  StringBuffer *buf = new StringBuffer ();
+
+  buf->append (JvNewStringLatin1 ("verification failed"));
+  if (pc != -1)
+    {
+      buf->append (JvNewStringLatin1 (" at PC "));
+      buf->append (pc);
+    }
+
+  buf->append (JvNewStringLatin1 (" in method "));
+  buf->append (current_class->getName());
+  buf->append ((jchar) '.');
+  buf->append (method->get_method()->name->toString());
+  buf->append ((jchar) '(');
+  buf->append (method->get_method()->signature->toString());
+  buf->append ((jchar) ')');
+
+  buf->append (JvNewStringLatin1 (": "));
+  buf->append (JvNewStringLatin1 (message));
+  throw new java::lang::VerifyError (buf->toString ());
+}
+
+inline void vfy_notify_verified (int pc)
+{
+  // In libgcj, do nothing.
+}
+
+// Return the primitive type corresponding to the argument to
+// `newarray'.
+inline vfy_jclass vfy_get_primitive_type (int type)
+{
+  switch (type)
+    {
+    case 4:
+      return JvPrimClass (boolean);
+    case 5:
+      return JvPrimClass (char);
+    case 6:
+      return JvPrimClass (float);
+    case 7:
+      return JvPrimClass (double);
+    case 8:
+      return JvPrimClass (byte);
+    case 9:
+      return JvPrimClass (short);
+    case 10:
+      return JvPrimClass (int);
+    case 11:
+      return JvPrimClass (long);
+    }
+  return NULL;
+}
+
+// Return true if this method comes from a 1.5 class file.
+inline bool vfy_is_15 (vfy_method *method)
+{
+  return false;			/* FIXME */
+}
+
+#define VFY_PRIMITIVE_CLASS(name) JvPrimClass (name)
+
+extern void _Jv_VerifyMethod (vfy_method *meth);
+
+#endif // JV_VERIFY_H


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