* 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).