constants.c (find_methodref_index): When the class is an interface...

d
	* constants.c (find_methodref_index):  When the class is an interface,
	generate CONSTANT_InterfaceMethodref instead of a CONSTANT_MethodRef.
	* decl.c (finit_identifier_node):  Use "$finit$", rather than
	"<finit>" (which Sun's verifier rejects).
	* parse.y (maybe_generate_finit):  Leave out meaningless final flag.
	(generate_field_initialization_code):  Removed.
	(fix_constructors)  Don't add call to $finit$ here (wrong order).
	(patch_method_invocation):  Add $finit$ call here.
	* java-tree.h (CALL_USING_SUPER):  New macro.
	* parse.y (patch_invoke):  Remove im local variable.
 	(patch_method_invocation, patch_invoke):  Don't pass super parameter.
	(patch_invoke):  Use CALL_USING_SUPER instead of from_super parameter.
	(resolve_qualified_expression_name):  Maybe set CALL_USING_SUPER.
	* jcf-write.c (get_access_flags):  Fix typo ACC_PUBLIC -> ACC_FINAL.
	* parse.y (java_complete_tree):  Don't complain about unreachable
	statement if it is empty_stmt_node.
	* jcf-write.c (find_constant_wide):  New function.
	(push_long_const):  Use find_constant_wide.
	* jcf-write.c (generate_bytecode_insn):  Fix bug in switch handling.
	(generate_bytecode_insn):  Use correct dup variant for MODIFY_EXPR.
	Add "redundant" NOTE_PUSH/NOTE_POP uses so code_SP_max gets set.
	Emit invokeinterface when calling an interface method.
	Emit invokespecial also when calling super or private methods.
	* jcf-write.c (generate_classfile):  Emit ConstantValue attributes.

From-SVN: r24163
This commit is contained in:
Per Bothner 1998-12-07 07:43:16 -08:00
parent 23a7b8f510
commit 89e09b9a23

View File

@ -114,7 +114,7 @@ static tree maybe_create_class_interface_decl PROTO ((tree, tree, tree));
static int check_class_interface_creation PROTO ((int, int, tree,
tree, tree, tree));
static tree patch_method_invocation PROTO ((tree, tree, tree,
int *, tree *, int));
int *, tree *));
static int breakdown_qualified PROTO ((tree *, tree *, tree));
static tree resolve_and_layout PROTO ((tree, tree));
static tree resolve_no_layout PROTO ((tree, tree));
@ -123,7 +123,7 @@ static tree find_applicable_accessible_methods_list PROTO ((int, tree,
tree, tree));
static tree find_most_specific_methods_list PROTO ((tree));
static int argument_types_convertible PROTO ((tree, tree));
static tree patch_invoke PROTO ((tree, tree, tree, int));
static tree patch_invoke PROTO ((tree, tree, tree));
static tree lookup_method_invoke PROTO ((int, tree, tree, tree, tree));
static tree register_incomplete_type PROTO ((int, tree, tree, tree));
static tree obtain_incomplete_type PROTO ((tree));
@ -224,7 +224,6 @@ static int verify_constructor_super PROTO (());
static tree create_artificial_method PROTO ((tree, int, tree, tree, tree));
static void start_artificial_method_body PROTO ((tree));
static void end_artificial_method_body PROTO ((tree));
static tree generate_field_initialization_code PROTO ((tree));
static int check_method_redefinition PROTO ((tree, tree));
static int reset_method_name PROTO ((tree));
static void java_check_regular_methods PROTO ((tree));
@ -3152,7 +3151,7 @@ register_fields (flags, type, variable_list)
lineno = saved_lineno;
}
/* Generate the method <finit> that initializes fields initialized
/* Generate the method $finit$ that initializes fields initialized
upon declaration. */
static void
@ -3164,7 +3163,7 @@ maybe_generate_finit ()
return;
mdecl = create_artificial_method (TREE_TYPE (ctxp->current_parsed_class),
ACC_PRIVATE|ACC_FINAL, void_type_node,
ACC_PRIVATE, void_type_node,
finit_identifier_node, end_params_node);
start_artificial_method_body (mdecl);
@ -4369,7 +4368,7 @@ check_method_redefinition (class, method)
tree redef, name;
tree cl = DECL_NAME (method);
tree sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
/* decl name of artificial <clinit> and <finit> doesn't need to be fixed and
/* decl name of artificial <clinit> and $finit$ doesn't need to be fixed and
checked */
/* Reset the method name before running the check. If it returns 1,
@ -5674,11 +5673,12 @@ fix_constructors (mdecl)
tree body = DECL_FUNCTION_BODY (mdecl);
tree field_init;
/* The constructor body must be crafted by hand. It's the
constructor we defined when we realize we didn't have the
CLASSNAME() constructor */
if (!body)
{
/* The constructor body must be crafted by hand. It's the
constructor we defined when we realize we didn't have the
CLASSNAME() constructor */
tree compound;
/* It is an error for the compiler to generate a default
@ -5699,11 +5699,6 @@ fix_constructors (mdecl)
compiling java.lang.Object. build_super_invocation takes care
of that. */
compound = java_method_add_stmt (mdecl, build_super_invocation ());
/* Takes care of non static field initialization */
field_init = generate_field_initialization_code (current_class);
if (field_init)
compound = java_method_add_stmt (mdecl, field_init);
end_artificial_method_body (mdecl);
}
@ -5737,11 +5732,6 @@ fix_constructors (mdecl)
compound = add_stmt_to_compound (compound, NULL_TREE,
build_super_invocation ());
/* Also fix its initialized fields initialization */
field_init = generate_field_initialization_code (current_class);
if (field_init)
compound = add_stmt_to_compound (compound, NULL_TREE, field_init);
/* Fix the constructor main block if we're adding extra stmts */
if (compound)
{
@ -5776,23 +5766,6 @@ verify_constructor_super ()
return 1;
}
/* Generate the code used to initialize field declared with an
initialization statement. For now, it returns a call the the
artificial function <finit>, if required. Always returns NULL if
nothing needs to be generated. */
static tree
generate_field_initialization_code (class)
tree class;
{
if (CLASS_HAS_FINIT_P (class))
return build_method_invocation (build_expr_wfl (finit_identifier_node,
input_filename, 0, 0),
NULL_TREE);
else
return NULL_TREE;
}
/* Expand finals. */
void
@ -6132,9 +6105,10 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
/* And code for the function call */
if (complete_function_arguments (qual_wfl))
return 1;
if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
CALL_USING_SUPER (qual_wfl) = 1;
*where_found =
patch_method_invocation (qual_wfl, decl, type,
&is_static, NULL, from_super);
patch_method_invocation (qual_wfl, decl, type, &is_static, NULL);
if (*where_found == error_mark_node)
return 1;
*type_found = type = QUAL_DECL_TYPE (*where_found);
@ -6559,17 +6533,17 @@ maybe_access_field (decl, where, type)
used. IS_STATIC is set to 1 if the invoked function is static. */
static tree
patch_method_invocation (patch, primary, where, is_static, ret_decl, super)
patch_method_invocation (patch, primary, where, is_static, ret_decl)
tree patch, primary, where;
int *is_static;
tree *ret_decl;
int super;
{
tree wfl = TREE_OPERAND (patch, 0);
tree args = TREE_OPERAND (patch, 1);
tree name = EXPR_WFL_NODE (wfl);
tree list;
int is_static_flag = 0;
int is_super_init = 0;
/* Should be overriden if everything goes well. Otherwise, if
something fails, it should keep this value. It stop the
@ -6690,6 +6664,7 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl, super)
else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
super_identifier_node)
{
is_super_init = 1;
if (CLASSTYPE_SUPER (current_class))
class_to_search =
DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
@ -6808,7 +6783,22 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl, super)
EH checking */
if (ret_decl)
*ret_decl = list;
return patch_invoke (patch, list, args, super);
patch = patch_invoke (patch, list, args);
if (is_super_init && CLASS_HAS_FINIT_P (current_class))
{
/* Generate the code used to initialize fields declared with an
initialization statement. For now, it returns a call the the
artificial function $finit$, if required. */
tree finit_call =
build_method_invocation (build_expr_wfl (finit_identifier_node,
input_filename, 0, 0),
NULL_TREE);
patch = build (COMPOUND_EXPR, void_type_node, patch,
java_complete_tree (finit_call));
CAN_COMPLETE_NORMALLY (patch) = 1;
}
return patch;
}
/* Check that we're not trying to do a static reference to a method in
@ -6836,11 +6826,9 @@ check_for_static_method_reference (wfl, node, method, where, primary)
mode. */
static tree
patch_invoke (patch, method, args, from_super)
patch_invoke (patch, method, args)
tree patch, method, args;
int from_super;
{
int im;
tree dtable, func;
tree original_call, t, ta;
@ -6861,7 +6849,7 @@ patch_invoke (patch, method, args, from_super)
else
{
tree signature = build_java_signature (TREE_TYPE (method));
switch ((im = invocation_mode (method, from_super)))
switch (invocation_mode (method, CALL_USING_SUPER (patch)))
{
case INVOKE_VIRTUAL:
dtable = invoke_build_dtable (0, args);
@ -6881,8 +6869,7 @@ patch_invoke (patch, method, args, from_super)
break;
default:
fatal ("Unknown invocation mode `%d' - build_invoke", im);
return NULL_TREE;
fatal ("internal error - unknown invocation_mode result");
}
/* Ensure self_type is initialized, (invokestatic). FIXME */
@ -7439,7 +7426,8 @@ java_complete_tree (node)
break;
}
if (TREE_CODE (wfl_op2) != CASE_EXPR
&& TREE_CODE (wfl_op2) != DEFAULT_EXPR)
&& TREE_CODE (wfl_op2) != DEFAULT_EXPR
&& wfl_op2 != empty_stmt_node)
unreachable_stmt_error (*ptr);
}
ptr = next;
@ -7608,7 +7596,8 @@ java_complete_tree (node)
case COMPOUND_EXPR:
wfl_op2 = TREE_OPERAND (node, 1);
TREE_OPERAND (node, 0) = nn = java_complete_tree (TREE_OPERAND (node, 0));
if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK
&& TREE_OPERAND (node, 1) != empty_stmt_node)
{
SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
parse_error_context (wfl_operator, "Unreachable statement");
@ -7689,7 +7678,7 @@ java_complete_tree (node)
int in_this = CALL_THIS_CONSTRUCTOR_P (node);
node = patch_method_invocation (node, NULL_TREE,
NULL_TREE, 0, &decl, 0);
NULL_TREE, 0, &decl);
if (node == error_mark_node)
return error_mark_node;