Commit 313ab5ee by Andrew Haley Committed by Andrew Haley

expr.c (build_field_ref): Pass NULL_TREE as SPECIAL arg to get_symbol_table_index().

2006-06-08  Andrew Haley  <aph@redhat.com>

        * expr.c (build_field_ref): Pass NULL_TREE as SPECIAL arg to
        get_symbol_table_index().
        (maybe_rewrite_invocation): Set SPECIAL if we need to access a
        private method.
        (build_known_method_ref): New arg: special.  Pass it to
        get_symbol_table_index.
        (get_symbol_table_index): Put SPECIAL in the TREE_PURPOSE field of
        the method list.
        (build_invokevirtual): New arg: special.  Pass it to
        get_symbol_table_index.
        (expand_invoke): New variable: special.
        Pass it to maybe_rewrite_invocation().
        Pass it to build_known_method_ref().
        * class.c (build_symbol_entry): Add new arg: special.  Use it to
        build the symbol table conbstructor.
        (emit_symbol_table): Extract SPECIAL from the method list and pass
        it to build_symbol_entry().
        * parse.y (patch_invoke): Call maybe_rewrite_invocation() and set
        special accordingly.

From-SVN: r114487
parent 297750da
2006-06-08 Andrew Haley <aph@redhat.com>
* expr.c (build_field_ref): Pass NULL_TREE as SPECIAL arg to
get_symbol_table_index().
(maybe_rewrite_invocation): Set SPECIAL if we need to access a
private method.
(build_known_method_ref): New arg: special. Pass it to
get_symbol_table_index.
(get_symbol_table_index): Put SPECIAL in the TREE_PURPOSE field of
the method list.
(build_invokevirtual): New arg: special. Pass it to
get_symbol_table_index.
(expand_invoke): New variable: special.
Pass it to maybe_rewrite_invocation().
Pass it to build_known_method_ref().
* class.c (build_symbol_entry): Add new arg: special. Use it to
build the symbol table conbstructor.
(emit_symbol_table): Extract SPECIAL from the method list and pass
it to build_symbol_entry().
* parse.y (patch_invoke): Call maybe_rewrite_invocation() and set
special accordingly.
2006-06-06 David Daney <ddaney@avtrex.com>
* gcj.texi (libgcj Runtime Properties): Document
......
......@@ -62,7 +62,7 @@ static int supers_all_compiled (tree type);
static tree maybe_layout_super_class (tree, tree);
static void add_miranda_methods (tree, tree);
static int assume_compiled (const char *);
static tree build_symbol_entry (tree);
static tree build_symbol_entry (tree, tree);
static tree emit_assertion_table (tree);
static void register_class (void);
......@@ -2651,7 +2651,7 @@ emit_register_classes (tree *list_p)
/* Make a symbol_type (_Jv_MethodSymbol) node for DECL. */
static tree
build_symbol_entry (tree decl)
build_symbol_entry (tree decl, tree special)
{
tree clname, name, signature, sym;
clname = build_utf8_ref (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl))));
......@@ -2667,6 +2667,12 @@ build_symbol_entry (tree decl)
signature = build_utf8_ref (unmangle_classname
(IDENTIFIER_POINTER (signature),
IDENTIFIER_LENGTH (signature)));
/* SPECIAL is either NULL_TREE or integer_one_node. We emit
signature addr+1 if SPECIAL, and this indicates to the runtime
system that this is a "special" symbol, i.e. one that should
bypass access controls. */
if (special != NULL_TREE)
signature = build2 (PLUS_EXPR, TREE_TYPE (signature), signature, special);
START_RECORD_CONSTRUCTOR (sym, symbol_type);
PUSH_FIELD_VALUE (sym, "clname", clname);
......@@ -2701,8 +2707,9 @@ emit_symbol_table (tree name, tree the_table, tree decl_list,
list = NULL_TREE;
while (method_list != NULL_TREE)
{
tree special = TREE_PURPOSE (method_list);
method = TREE_VALUE (method_list);
list = tree_cons (NULL_TREE, build_symbol_entry (method), list);
list = tree_cons (NULL_TREE, build_symbol_entry (method, special), list);
method_list = TREE_CHAIN (method_list);
index++;
}
......
......@@ -1711,7 +1711,8 @@ build_field_ref (tree self_value, tree self_class, tree name)
{
tree otable_index
= build_int_cst (NULL_TREE, get_symbol_table_index
(field_decl, &TYPE_OTABLE_METHODS (output_class)));
(field_decl, NULL_TREE,
&TYPE_OTABLE_METHODS (output_class)));
tree field_offset
= build4 (ARRAY_REF, integer_type_node,
TYPE_OTABLE_DECL (output_class), otable_index,
......@@ -2060,14 +2061,17 @@ static rewrite_rule rules[] =
{NULL, NULL, NULL, NULL, 0, NULL}};
/* Scan the rules list for replacements for *METHOD_P and replace the
args accordingly. */
args accordingly. If the rewrite results in an access to a private
method, update SPECIAL.*/
void
maybe_rewrite_invocation (tree *method_p, tree *arg_list_p,
tree *method_signature_p)
tree *method_signature_p, tree *special)
{
tree context = DECL_NAME (TYPE_NAME (DECL_CONTEXT (*method_p)));
rewrite_rule *p;
*special = NULL_TREE;
for (p = rules; p->classname; p++)
{
if (get_identifier (p->classname) == context)
......@@ -2091,6 +2095,7 @@ maybe_rewrite_invocation (tree *method_p, tree *arg_list_p,
gcc_assert (*method_p);
*arg_list_p = p->rewrite_arglist (*arg_list_p);
*method_signature_p = get_identifier (p->new_signature);
*special = integer_one_node;
break;
}
......@@ -2103,7 +2108,7 @@ maybe_rewrite_invocation (tree *method_p, tree *arg_list_p,
tree
build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
tree self_type, tree method_signature ATTRIBUTE_UNUSED,
tree arg_list ATTRIBUTE_UNUSED)
tree arg_list ATTRIBUTE_UNUSED, tree special)
{
tree func;
if (is_compiled_class (self_type))
......@@ -2121,8 +2126,10 @@ build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
else
{
tree table_index
= build_int_cst (NULL_TREE, get_symbol_table_index
(method, &TYPE_ATABLE_METHODS (output_class)));
= build_int_cst (NULL_TREE,
(get_symbol_table_index
(method, special,
&TYPE_ATABLE_METHODS (output_class))));
func
= build4 (ARRAY_REF,
TREE_TYPE (TREE_TYPE (TYPE_ATABLE_DECL (output_class))),
......@@ -2207,14 +2214,14 @@ invoke_build_dtable (int is_invoke_interface, tree arg_list)
reused. */
int
get_symbol_table_index (tree t, tree *symbol_table)
get_symbol_table_index (tree t, tree special, tree *symbol_table)
{
int i = 1;
tree method_list;
if (*symbol_table == NULL_TREE)
{
*symbol_table = build_tree_list (t, t);
*symbol_table = build_tree_list (special, t);
return 1;
}
......@@ -2223,7 +2230,8 @@ get_symbol_table_index (tree t, tree *symbol_table)
while (1)
{
tree value = TREE_VALUE (method_list);
if (value == t)
tree purpose = TREE_PURPOSE (method_list);
if (value == t && purpose == special)
return i;
i++;
if (TREE_CHAIN (method_list) == NULL_TREE)
......@@ -2232,12 +2240,12 @@ get_symbol_table_index (tree t, tree *symbol_table)
method_list = TREE_CHAIN (method_list);
}
TREE_CHAIN (method_list) = build_tree_list (t, t);
TREE_CHAIN (method_list) = build_tree_list (special, t);
return i;
}
tree
build_invokevirtual (tree dtable, tree method)
build_invokevirtual (tree dtable, tree method, tree special)
{
tree func;
tree nativecode_ptr_ptr_type_node
......@@ -2251,7 +2259,8 @@ build_invokevirtual (tree dtable, tree method)
otable_index
= build_int_cst (NULL_TREE, get_symbol_table_index
(method, &TYPE_OTABLE_METHODS (output_class)));
(method, special,
&TYPE_OTABLE_METHODS (output_class)));
method_index = build4 (ARRAY_REF, integer_type_node,
TYPE_OTABLE_DECL (output_class),
otable_index, NULL_TREE, NULL_TREE);
......@@ -2307,7 +2316,7 @@ build_invokeinterface (tree dtable, tree method)
{
int itable_index
= 2 * (get_symbol_table_index
(method, &TYPE_ITABLE_METHODS (output_class)));
(method, NULL_TREE, &TYPE_ITABLE_METHODS (output_class)));
interface
= build4 (ARRAY_REF,
TREE_TYPE (TREE_TYPE (TYPE_ITABLE_DECL (output_class))),
......@@ -2360,6 +2369,8 @@ expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
tree call, func, method, arg_list, method_type;
tree check = NULL_TREE;
tree special = NULL_TREE;
if (! CLASS_LOADED_P (self_type))
{
load_class (self_type, 1);
......@@ -2474,12 +2485,13 @@ expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
flush_quick_stack ();
maybe_rewrite_invocation (&method, &arg_list, &method_signature);
maybe_rewrite_invocation (&method, &arg_list, &method_signature,
&special);
func = NULL_TREE;
if (opcode == OPCODE_invokestatic)
func = build_known_method_ref (method, method_type, self_type,
method_signature, arg_list);
method_signature, arg_list, special);
else if (opcode == OPCODE_invokespecial
|| (opcode == OPCODE_invokevirtual
&& (METHOD_PRIVATE (method)
......@@ -2499,14 +2511,14 @@ expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
TREE_VALUE (arg_list) = save_arg;
check = java_check_reference (save_arg, ! DECL_INIT_P (method));
func = build_known_method_ref (method, method_type, self_type,
method_signature, arg_list);
method_signature, arg_list, special);
}
else
{
tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
arg_list);
if (opcode == OPCODE_invokevirtual)
func = build_invokevirtual (dtable, method);
func = build_invokevirtual (dtable, method, special);
else
func = build_invokeinterface (dtable, method);
}
......
......@@ -1241,11 +1241,11 @@ extern tree check_for_builtin (tree, tree);
extern void initialize_builtins (void);
extern tree lookup_name (tree);
extern void maybe_rewrite_invocation (tree *, tree *, tree *);
extern tree build_known_method_ref (tree, tree, tree, tree, tree);
extern void maybe_rewrite_invocation (tree *, tree *, tree *, tree *);
extern tree build_known_method_ref (tree, tree, tree, tree, tree, tree);
extern tree build_class_init (tree, tree);
extern int attach_init_test_initialization_flags (void **, void *);
extern tree build_invokevirtual (tree, tree);
extern tree build_invokevirtual (tree, tree, tree);
extern tree build_invokeinterface (tree, tree);
extern tree build_jni_stub (tree);
extern tree invoke_build_dtable (int, tree);
......@@ -1393,7 +1393,7 @@ extern void register_exception_range(struct eh_range *, int, int);
extern void finish_method (tree);
extern void java_expand_body (tree);
extern int get_symbol_table_index (tree, tree *);
extern int get_symbol_table_index (tree, tree, tree *);
extern tree make_catch_class_record (tree, tree);
extern tree emit_catch_table (tree);
......
......@@ -11043,8 +11043,14 @@ patch_invoke (tree patch, tree method, tree args)
switch (invocation_mode (method, CALL_USING_SUPER (patch)))
{
case INVOKE_VIRTUAL:
dtable = invoke_build_dtable (0, args);
func = build_invokevirtual (dtable, method);
{
tree signature = build_java_signature (TREE_TYPE (method));
tree special;
maybe_rewrite_invocation (&method, &args, &signature, &special);
dtable = invoke_build_dtable (0, args);
func = build_invokevirtual (dtable, method, special);
}
break;
case INVOKE_NONVIRTUAL:
......@@ -11066,10 +11072,11 @@ patch_invoke (tree patch, tree method, tree args)
case INVOKE_STATIC:
{
tree signature = build_java_signature (TREE_TYPE (method));
maybe_rewrite_invocation (&method, &args, &signature);
tree special;
maybe_rewrite_invocation (&method, &args, &signature, &special);
func = build_known_method_ref (method, TREE_TYPE (method),
DECL_CONTEXT (method),
signature, args);
signature, args, special);
}
break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment