Added Java 1.1 language features.

From-SVN: r32517
parent e4476d1c
...@@ -374,13 +374,9 @@ check_init (exp, before) ...@@ -374,13 +374,9 @@ check_init (exp, before)
int index = DECL_BIT_INDEX (exp); int index = DECL_BIT_INDEX (exp);
if (index >= 0 && ! SET_P (before, index)) if (index >= 0 && ! SET_P (before, index))
{ {
#if 1 parse_error_context
parse_error_context (wfl, (wfl, "Variable `%s' may not have been initialized",
"Variable `%s' may not have been initialized" IDENTIFIER_POINTER (DECL_NAME (exp)));
, IDENTIFIER_POINTER (DECL_NAME (exp)));
#else
error_with_decl (exp, "variable may be used uninitialized");
#endif
/* Suppress further errors. */ /* Suppress further errors. */
DECL_BIT_INDEX (exp) = -1; DECL_BIT_INDEX (exp) = -1;
} }
...@@ -388,11 +384,20 @@ check_init (exp, before) ...@@ -388,11 +384,20 @@ check_init (exp, before)
break; break;
case MODIFY_EXPR: case MODIFY_EXPR:
tmp = TREE_OPERAND (exp, 0); tmp = TREE_OPERAND (exp, 0);
if (TREE_CODE (tmp) == VAR_DECL && ! FIELD_STATIC (tmp)) /* We're interested in variable declaration and parameter
declaration when they're declared with the `final' modifier. */
if ((TREE_CODE (tmp) == VAR_DECL && ! FIELD_STATIC (tmp))
|| (TREE_CODE (tmp) == PARM_DECL && LOCAL_FINAL (tmp)))
{ {
int index; int index;
check_init (TREE_OPERAND (exp, 1), before); check_init (TREE_OPERAND (exp, 1), before);
index = DECL_BIT_INDEX (tmp); index = DECL_BIT_INDEX (tmp);
/* A final local already assigned or a final parameter
assigned must be reported as errors */
if (LOCAL_FINAL (tmp)
&& (index == -1 || TREE_CODE (tmp) == PARM_DECL))
parse_error_context (wfl, "Can't assign here a value to the `final' variable `%s'", IDENTIFIER_POINTER (DECL_NAME (tmp)));
if (index >= 0) if (index >= 0)
SET_BIT (before, index); SET_BIT (before, index);
/* Minor optimization. See comment for start_current_locals. */ /* Minor optimization. See comment for start_current_locals. */
......
...@@ -282,6 +282,7 @@ make_class () ...@@ -282,6 +282,7 @@ make_class ()
#else #else
TYPE_BINFO (type) = make_tree_vec (6); TYPE_BINFO (type) = make_tree_vec (6);
#endif #endif
MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC (type);
pop_obstacks (); pop_obstacks ();
return type; return type;
...@@ -395,6 +396,7 @@ set_super_info (access_flags, this_class, super_class, interfaces_count) ...@@ -395,6 +396,7 @@ set_super_info (access_flags, this_class, super_class, interfaces_count)
if (access_flags & ACC_SUPER) CLASS_SUPER (class_decl) = 1; if (access_flags & ACC_SUPER) CLASS_SUPER (class_decl) = 1;
if (access_flags & ACC_INTERFACE) CLASS_INTERFACE (class_decl) = 1; if (access_flags & ACC_INTERFACE) CLASS_INTERFACE (class_decl) = 1;
if (access_flags & ACC_ABSTRACT) CLASS_ABSTRACT (class_decl) = 1; if (access_flags & ACC_ABSTRACT) CLASS_ABSTRACT (class_decl) = 1;
if (access_flags & ACC_STATIC) CLASS_STATIC (class_decl) = 1;
} }
/* Return length of inheritance chain of CLAS, where java.lang.Object is 0, /* Return length of inheritance chain of CLAS, where java.lang.Object is 0,
...@@ -460,6 +462,27 @@ inherits_from_p (type1, type2) ...@@ -460,6 +462,27 @@ inherits_from_p (type1, type2)
return 0; return 0;
} }
/* Return a 1 iff TYPE1 is an enclosing context for TYPE2 */
int
enclosing_context_p (type1, type2)
tree type1, type2;
{
if (!INNER_CLASS_TYPE_P (type2))
return 0;
for (type2 = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type2)));
type2;
type2 = (INNER_CLASS_TYPE_P (type2) ?
TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type2))) : NULL_TREE))
{
if (type2 == type1)
return 1;
}
return 0;
}
static void static void
add_interface_do (basetype_vec, interface_class, i) add_interface_do (basetype_vec, interface_class, i)
tree basetype_vec, interface_class; tree basetype_vec, interface_class;
...@@ -1016,6 +1039,8 @@ get_access_flags_from_decl (decl) ...@@ -1016,6 +1039,8 @@ get_access_flags_from_decl (decl)
access_flags |= ACC_INTERFACE; access_flags |= ACC_INTERFACE;
if (CLASS_ABSTRACT (decl)) if (CLASS_ABSTRACT (decl))
access_flags |= ACC_ABSTRACT; access_flags |= ACC_ABSTRACT;
if (CLASS_STATIC (decl))
access_flags |= ACC_STATIC;
return access_flags; return access_flags;
} }
if (TREE_CODE (decl) == FUNCTION_DECL) if (TREE_CODE (decl) == FUNCTION_DECL)
...@@ -1457,8 +1482,7 @@ is_compiled_class (class) ...@@ -1457,8 +1482,7 @@ is_compiled_class (class)
if (class == current_class) if (class == current_class)
return 2; return 2;
seen_in_zip = (TYPE_LANG_SPECIFIC (class) && TYPE_LANG_SPECIFIC (class)->jcf seen_in_zip = (TYPE_JCF (class) && TYPE_JCF (class)->seen_in_zip);
&& TYPE_LANG_SPECIFIC (class)->jcf->seen_in_zip);
if (CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (class) || seen_in_zip) if (CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (class) || seen_in_zip)
{ {
/* The class was seen in the current ZIP file and will be /* The class was seen in the current ZIP file and will be
...@@ -1635,6 +1659,9 @@ push_super_field (this_class, super_class) ...@@ -1635,6 +1659,9 @@ push_super_field (this_class, super_class)
tree this_class, super_class; tree this_class, super_class;
{ {
tree base_decl; tree base_decl;
/* Don't insert the field if we're just re-laying the class out. */
if (TYPE_FIELDS (this_class) && !DECL_NAME (TYPE_FIELDS (this_class)))
return;
push_obstacks (&permanent_obstack, &permanent_obstack); push_obstacks (&permanent_obstack, &permanent_obstack);
base_decl = build_decl (FIELD_DECL, NULL_TREE, super_class); base_decl = build_decl (FIELD_DECL, NULL_TREE, super_class);
pop_obstacks (); pop_obstacks ();
...@@ -1668,7 +1695,8 @@ maybe_layout_super_class (super_class, this_class) ...@@ -1668,7 +1695,8 @@ maybe_layout_super_class (super_class, this_class)
super_class = TREE_TYPE (super_class); super_class = TREE_TYPE (super_class);
else else
{ {
super_class = do_resolve_class (super_class, NULL_TREE, this_class); super_class = do_resolve_class (NULL_TREE, /* FIXME? */
super_class, NULL_TREE, this_class);
if (!super_class) if (!super_class)
return NULL_TREE; /* FIXME, NULL_TREE not checked by caller. */ return NULL_TREE; /* FIXME, NULL_TREE not checked by caller. */
super_class = TREE_TYPE (super_class); super_class = TREE_TYPE (super_class);
...@@ -1684,8 +1712,36 @@ void ...@@ -1684,8 +1712,36 @@ void
layout_class (this_class) layout_class (this_class)
tree this_class; tree this_class;
{ {
static tree list = NULL_TREE;
tree super_class = CLASSTYPE_SUPER (this_class); tree super_class = CLASSTYPE_SUPER (this_class);
tree field; tree field;
list = tree_cons (this_class, NULL_TREE, list);
if (CLASS_BEING_LAIDOUT (this_class))
{
char buffer [1024];
tree current;
sprintf (buffer, " with `%s'",
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))));
obstack_grow (&temporary_obstack, buffer, strlen (buffer));
for (current = TREE_CHAIN (list); current;
current = TREE_CHAIN (current))
{
tree decl = TYPE_NAME (TREE_PURPOSE (current));
sprintf (buffer, "\n which inherits from `%s' (%s:%d)",
IDENTIFIER_POINTER (DECL_NAME (decl)),
DECL_SOURCE_FILE (decl),
DECL_SOURCE_LINE (decl));
obstack_grow (&temporary_obstack, buffer, strlen (buffer));
}
obstack_1grow (&temporary_obstack, '\0');
cyclic_inheritance_report = obstack_finish (&temporary_obstack);
TYPE_SIZE (this_class) = error_mark_node;
return;
}
CLASS_BEING_LAIDOUT (this_class) = 1;
if (super_class) if (super_class)
{ {
...@@ -1693,6 +1749,8 @@ layout_class (this_class) ...@@ -1693,6 +1749,8 @@ layout_class (this_class)
if (TREE_CODE (TYPE_SIZE (super_class)) == ERROR_MARK) if (TREE_CODE (TYPE_SIZE (super_class)) == ERROR_MARK)
{ {
TYPE_SIZE (this_class) = error_mark_node; TYPE_SIZE (this_class) = error_mark_node;
CLASS_BEING_LAIDOUT (this_class) = 0;
list = TREE_CHAIN (list);
return; return;
} }
if (TYPE_SIZE (this_class) == NULL_TREE) if (TYPE_SIZE (this_class) == NULL_TREE)
...@@ -1714,6 +1772,9 @@ layout_class (this_class) ...@@ -1714,6 +1772,9 @@ layout_class (this_class)
/* Convert the size back to an SI integer value */ /* Convert the size back to an SI integer value */
TYPE_SIZE_UNIT (this_class) = TYPE_SIZE_UNIT (this_class) =
fold (convert (int_type_node, TYPE_SIZE_UNIT (this_class))); fold (convert (int_type_node, TYPE_SIZE_UNIT (this_class)));
CLASS_BEING_LAIDOUT (this_class) = 0;
list = TREE_CHAIN (list);
} }
void void
...@@ -1772,8 +1833,7 @@ layout_class_method (this_class, super_class, method_decl, dtable_count) ...@@ -1772,8 +1833,7 @@ layout_class_method (this_class, super_class, method_decl, dtable_count)
if (method_name_is_wfl) if (method_name_is_wfl)
method_name = java_get_real_method_name (method_decl); method_name = java_get_real_method_name (method_decl);
if (method_name != init_identifier_node if (!ID_INIT_P (method_name) && !ID_FINIT_P (method_name))
&& method_name != finit_identifier_node)
{ {
int encoded_len int encoded_len
= unicode_mangling_length (IDENTIFIER_POINTER (method_name), = unicode_mangling_length (IDENTIFIER_POINTER (method_name),
...@@ -1794,7 +1854,7 @@ layout_class_method (this_class, super_class, method_decl, dtable_count) ...@@ -1794,7 +1854,7 @@ layout_class_method (this_class, super_class, method_decl, dtable_count)
} }
obstack_grow (&temporary_obstack, "__", 2); obstack_grow (&temporary_obstack, "__", 2);
if (method_name == finit_identifier_node) if (ID_FINIT_P (method_name))
obstack_grow (&temporary_obstack, "finit", 5); obstack_grow (&temporary_obstack, "finit", 5);
append_gpp_mangled_type (&temporary_obstack, this_class); append_gpp_mangled_type (&temporary_obstack, this_class);
TREE_PUBLIC (method_decl) = 1; TREE_PUBLIC (method_decl) = 1;
...@@ -1856,11 +1916,11 @@ layout_class_method (this_class, super_class, method_decl, dtable_count) ...@@ -1856,11 +1916,11 @@ layout_class_method (this_class, super_class, method_decl, dtable_count)
it's an interface method that isn't clinit. */ it's an interface method that isn't clinit. */
if (! METHOD_ABSTRACT (method_decl) if (! METHOD_ABSTRACT (method_decl)
|| (CLASS_INTERFACE (TYPE_NAME (this_class)) || (CLASS_INTERFACE (TYPE_NAME (this_class))
&& (IS_CLINIT (method_decl)))) && (DECL_CLINIT_P (method_decl))))
make_function_rtl (method_decl); make_function_rtl (method_decl);
obstack_free (&temporary_obstack, asm_name); obstack_free (&temporary_obstack, asm_name);
if (method_name == init_identifier_node) if (ID_INIT_P (method_name))
{ {
const char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))); const char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
for (ptr = p; *ptr; ) for (ptr = p; *ptr; )
......
...@@ -390,7 +390,10 @@ alloc_class_constant (clas) ...@@ -390,7 +390,10 @@ alloc_class_constant (clas)
static tree static tree
build_constant_data_ref () build_constant_data_ref ()
{ {
if (current_constant_pool_data_ref == NULL_TREE) if (TYPE_CPOOL_DATA_REF (current_class))
current_constant_pool_data_ref = TYPE_CPOOL_DATA_REF (current_class);
else if (current_constant_pool_data_ref == NULL_TREE)
{ {
tree decl; tree decl;
tree decl_name = mangled_classname ("_CD_", current_class); tree decl_name = mangled_classname ("_CD_", current_class);
...@@ -401,7 +404,7 @@ build_constant_data_ref () ...@@ -401,7 +404,7 @@ build_constant_data_ref ()
TREE_STATIC (decl) = 1; TREE_STATIC (decl) = 1;
make_decl_rtl (decl, NULL, 1); make_decl_rtl (decl, NULL, 1);
pop_obstacks (); pop_obstacks ();
current_constant_pool_data_ref TYPE_CPOOL_DATA_REF (current_class) = current_constant_pool_data_ref
= build1 (ADDR_EXPR, ptr_type_node, decl); = build1 (ADDR_EXPR, ptr_type_node, decl);
} }
return current_constant_pool_data_ref; return current_constant_pool_data_ref;
......
...@@ -360,7 +360,7 @@ tree length_identifier_node; ...@@ -360,7 +360,7 @@ tree length_identifier_node;
tree this_identifier_node; tree this_identifier_node;
tree super_identifier_node; tree super_identifier_node;
tree continue_identifier_node; tree continue_identifier_node;
tree access0_identifier_node; /* 1.1 */
tree end_params_node; tree end_params_node;
/* References to internal libjava functions we use. */ /* References to internal libjava functions we use. */
...@@ -460,6 +460,7 @@ init_decl_processing () ...@@ -460,6 +460,7 @@ init_decl_processing ()
error_mark_node = make_node (ERROR_MARK); error_mark_node = make_node (ERROR_MARK);
TREE_TYPE (error_mark_node) = error_mark_node; TREE_TYPE (error_mark_node) = error_mark_node;
initialize_sizetypes ();
/* Create sizetype first - needed for other types. */ /* Create sizetype first - needed for other types. */
initialize_sizetypes (); initialize_sizetypes ();
set_sizetype (make_unsigned_type (POINTER_SIZE)); set_sizetype (make_unsigned_type (POINTER_SIZE));
...@@ -601,6 +602,7 @@ init_decl_processing () ...@@ -601,6 +602,7 @@ init_decl_processing ()
this_identifier_node = get_identifier ("this"); this_identifier_node = get_identifier ("this");
super_identifier_node = get_identifier ("super"); super_identifier_node = get_identifier ("super");
continue_identifier_node = get_identifier ("continue"); continue_identifier_node = get_identifier ("continue");
access0_identifier_node = get_identifier ("access$0");
/* for lack of a better place to put this stub call */ /* for lack of a better place to put this stub call */
init_expr_processing(); init_expr_processing();
...@@ -965,8 +967,9 @@ pushdecl (x) ...@@ -965,8 +967,9 @@ pushdecl (x)
register tree t; register tree t;
register tree name = DECL_NAME (x); register tree name = DECL_NAME (x);
register struct binding_level *b = current_binding_level; register struct binding_level *b = current_binding_level;
DECL_CONTEXT (x) = current_function_decl; if (TREE_CODE (x) != TYPE_DECL)
DECL_CONTEXT (x) = current_function_decl;
if (name) if (name)
{ {
const char *file; const char *file;
...@@ -1629,7 +1632,6 @@ build_result_decl (fndecl) ...@@ -1629,7 +1632,6 @@ build_result_decl (fndecl)
return (DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, restype)); return (DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, restype));
} }
/* Called for every element in DECL_FUNCTION_INIT_TEST_TABLE in order /* Called for every element in DECL_FUNCTION_INIT_TEST_TABLE in order
to emit initialization code for each test flag. */ to emit initialization code for each test flag. */
......
...@@ -1263,6 +1263,16 @@ lookup_field (typep, name) ...@@ -1263,6 +1263,16 @@ lookup_field (typep, name)
if (DECL_NAME (field) == name) if (DECL_NAME (field) == name)
return field; return field;
/* If *typep is an innerclass, lookup the field in its enclosing
contexts */
if (INNER_CLASS_TYPE_P (*typep))
{
tree outer_type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (*typep)));
if ((field = lookup_field (&outer_type, name)))
return field;
}
/* Process implemented interfaces. */ /* Process implemented interfaces. */
basetype_vec = TYPE_BINFO_BASETYPES (*typep); basetype_vec = TYPE_BINFO_BASETYPES (*typep);
n = TREE_VEC_LENGTH (basetype_vec); n = TREE_VEC_LENGTH (basetype_vec);
...@@ -1721,7 +1731,7 @@ expand_invoke (opcode, method_ref_index, nargs) ...@@ -1721,7 +1731,7 @@ expand_invoke (opcode, method_ref_index, nargs)
} }
layout_class_methods (self_type); layout_class_methods (self_type);
if (method_name == init_identifier_node) if (ID_INIT_P (method_name))
method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type), method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
method_signature); method_signature);
else else
...@@ -1881,7 +1891,7 @@ expand_java_field_op (is_static, is_putting, field_ref_index) ...@@ -1881,7 +1891,7 @@ expand_java_field_op (is_static, is_putting, field_ref_index)
"assignment to final field `%s' not in field's class"); "assignment to final field `%s' not in field's class");
else if (FIELD_STATIC (field_decl)) else if (FIELD_STATIC (field_decl))
{ {
if (!IS_CLINIT (current_function_decl)) if (!DECL_CLINIT_P (current_function_decl))
error_with_decl (field_decl, error_with_decl (field_decl,
"assignment to final static field `%s' not in class initializer"); "assignment to final static field `%s' not in class initializer");
} }
...@@ -2013,10 +2023,8 @@ java_lang_expand_expr (exp, target, tmode, modifier) ...@@ -2013,10 +2023,8 @@ java_lang_expand_expr (exp, target, tmode, modifier)
if (TREE_CONSTANT (init) if (TREE_CONSTANT (init)
&& ilength >= 10 && JPRIMITIVE_TYPE_P (element_type)) && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
{ {
tree init_decl; tree init_decl = build_decl (VAR_DECL, generate_name (),
push_obstacks (&permanent_obstack, &permanent_obstack); TREE_TYPE (init));
init_decl = build_decl (VAR_DECL, generate_name (),
TREE_TYPE (init));
pushdecl_top_level (init_decl); pushdecl_top_level (init_decl);
TREE_STATIC (init_decl) = 1; TREE_STATIC (init_decl) = 1;
DECL_INITIAL (init_decl) = init; DECL_INITIAL (init_decl) = init;
...@@ -2024,7 +2032,6 @@ java_lang_expand_expr (exp, target, tmode, modifier) ...@@ -2024,7 +2032,6 @@ java_lang_expand_expr (exp, target, tmode, modifier)
TREE_READONLY (init_decl) = 1; TREE_READONLY (init_decl) = 1;
TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1; TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
make_decl_rtl (init_decl, NULL, 1); make_decl_rtl (init_decl, NULL, 1);
pop_obstacks ();
init = init_decl; init = init_decl;
} }
expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld), expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
......
...@@ -22,6 +22,13 @@ DEFTREECODE (UNARY_PLUS_EXPR, "unary_plus_expr", '1', 1) ...@@ -22,6 +22,13 @@ DEFTREECODE (UNARY_PLUS_EXPR, "unary_plus_expr", '1', 1)
Once patched, the node will bear the type of the created array. */ Once patched, the node will bear the type of the created array. */
DEFTREECODE (NEW_ARRAY_EXPR, "new_array_expr", 'e', 3) DEFTREECODE (NEW_ARRAY_EXPR, "new_array_expr", 'e', 3)
/* New anonymous array creation expression.
Operand 0 is the base type of the anonymous array.
Operand 1 is the signature of the dimensions this array contains.
Operand 2 is the anonymous array initializer.
Once patched, the node will bear the type of the created array. */
DEFTREECODE (NEW_ANONYMOUS_ARRAY_EXPR, "new_anonymous_array", 'e', 3)
/* New class creation expression. /* New class creation expression.
Operand 0 is the name of the class to be created Operand 0 is the name of the class to be created
Operand 1 is the argument list used to select a constructor. Operand 1 is the argument list used to select a constructor.
...@@ -75,3 +82,14 @@ DEFTREECODE (INSTANCEOF_EXPR, "instanceof", 'e', 2) ...@@ -75,3 +82,14 @@ DEFTREECODE (INSTANCEOF_EXPR, "instanceof", 'e', 2)
when the node is created. when the node is created.
Operand 1 is a CONSTRUCTOR node. */ Operand 1 is a CONSTRUCTOR node. */
DEFTREECODE (NEW_ARRAY_INIT, "new_array_init", '1', 1) DEFTREECODE (NEW_ARRAY_INIT, "new_array_init", '1', 1)
/* Class literal.
Operand 0 is the name of the class we're trying to build a
reference from. */
DEFTREECODE (CLASS_LITERAL, "class_litteral", '1', 1)
/* Instance initializer.
Operand 0 contains the intance initializer statement. This tree node
is used for context detection, so that special rules can be
enforced. */
DEFTREECODE (INSTANCE_INITIALIZERS_EXPR, "instance_initializers_expr", '1', 1)
...@@ -294,6 +294,38 @@ DEFUN(utf8_equal_string, (jcf, index, value), ...@@ -294,6 +294,38 @@ DEFUN(utf8_equal_string, (jcf, index, value),
else \ else \
JCF_SKIP (jcf, 4 * n); } JCF_SKIP (jcf, 4 * n); }
#define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) \
{ int n = (COUNT); \
COMMON_HANDLE_ATTRIBUTE(jcf, attribute_name, attribute_length); \
while (n--) \
{ \
uint16 inner_class_info_index = JCF_readu2 (jcf); \
uint16 outer_class_info_index = JCF_readu2 (jcf); \
uint16 inner_name_index = JCF_readu2 (jcf); \
uint16 inner_class_access_flags = JCF_readu2 (jcf); \
\
if (flag_print_class_info) \
{ \
fprintf (out, "\n class: "); \
if (flag_print_constant_pool) \
fprintf (out, "%d=", inner_class_info_index); \
print_constant_terse (out, jcf, \
inner_class_info_index, CONSTANT_Class); \
fprintf (out, " (%d=", inner_name_index); \
print_constant_terse (out, jcf, inner_name_index, CONSTANT_Utf8); \
fprintf (out, "), access flags: 0x%x", inner_class_access_flags); \
print_access_flags (out, inner_class_access_flags, 'c'); \
fprintf (out, ", outer class: "); \
if (flag_print_constant_pool) \
fprintf (out, "%d=", outer_class_info_index); \
print_constant_terse (out, jcf, \
outer_class_info_index, CONSTANT_Class); \
} \
} \
if (flag_print_class_info) \
fputc ('\n', out); \
}
#define PROCESS_OTHER_ATTRIBUTE(JCF, INDEX, LENGTH) \ #define PROCESS_OTHER_ATTRIBUTE(JCF, INDEX, LENGTH) \
{ COMMON_HANDLE_ATTRIBUTE(JCF, INDEX, LENGTH); \ { COMMON_HANDLE_ATTRIBUTE(JCF, INDEX, LENGTH); \
fputc ('\n', out); JCF_SKIP (JCF, LENGTH); } fputc ('\n', out); JCF_SKIP (JCF, LENGTH); }
......
...@@ -185,6 +185,32 @@ set_source_filename (jcf, index) ...@@ -185,6 +185,32 @@ set_source_filename (jcf, index)
DECL_FUNCTION_THROWS (current_method) = nreverse (list); \ DECL_FUNCTION_THROWS (current_method) = nreverse (list); \
} }
/* Link seen inner classes to their outer context and register the
inner class to its outer context. They will be later loaded. */
#define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) \
{ \
int c = (count); \
while (c--) \
{ \
tree class = get_class_constant (jcf, JCF_readu2 (jcf)); \
if (!CLASS_COMPLETE_P (class)) \
{ \
tree outer = TYPE_NAME (get_class_constant (jcf, \
JCF_readu2 (jcf))); \
tree alias = get_name_constant (jcf, JCF_readu2 (jcf)); \
tree decl = TYPE_NAME (class); \
JCF_SKIP (jcf, 2); \
IDENTIFIER_GLOBAL_VALUE (alias) = decl; \
DECL_CONTEXT (decl) = outer; \
DECL_INNER_CLASS_LIST (outer) = \
tree_cons (decl, alias, DECL_INNER_CLASS_LIST (outer)); \
CLASS_COMPLETE_P (class) = 1; \
} \
else \
JCF_SKIP (jcf, 6); \
} \
}
#include "jcf-reader.c" #include "jcf-reader.c"
static int yydebug; static int yydebug;
...@@ -565,6 +591,7 @@ jcf_parse (jcf) ...@@ -565,6 +591,7 @@ jcf_parse (jcf)
JCF* jcf; JCF* jcf;
{ {
int i, code; int i, code;
tree current;
if (jcf_parse_preamble (jcf) != 0) if (jcf_parse_preamble (jcf) != 0)
fatal ("Not a valid Java .class file.\n"); fatal ("Not a valid Java .class file.\n");
...@@ -617,23 +644,21 @@ jcf_parse (jcf) ...@@ -617,23 +644,21 @@ jcf_parse (jcf)
else else
all_class_list = tree_cons (NULL_TREE, all_class_list = tree_cons (NULL_TREE,
TYPE_NAME (current_class), all_class_list ); TYPE_NAME (current_class), all_class_list );
/* And if we came accross inner classes, load them now. */
for (current = DECL_INNER_CLASS_LIST (TYPE_NAME (current_class)); current;
current = TREE_CHAIN (current))
load_class (DECL_NAME (TREE_PURPOSE (current)), 1);
pop_obstacks (); pop_obstacks ();
} }
void void
init_outgoing_cpool () init_outgoing_cpool ()
{ {
current_constant_pool_data_ref = NULL_TREE; current_constant_pool_data_ref = NULL_TREE;
if (outgoing_cpool == NULL) outgoing_cpool = (struct CPool *)xmalloc (sizeof (struct CPool));
{ bzero (outgoing_cpool, sizeof (struct CPool));
static CPool outgoing_cpool_buffer;
outgoing_cpool = &outgoing_cpool_buffer;
CPOOL_INIT(outgoing_cpool);
}
else
{
CPOOL_REINIT(outgoing_cpool);
}
} }
static void static void
...@@ -737,6 +762,7 @@ parse_source_file (file) ...@@ -737,6 +762,7 @@ parse_source_file (file)
java_parse_abort_on_error (); java_parse_abort_on_error ();
java_fix_constructors (); /* Fix the constructors */ java_fix_constructors (); /* Fix the constructors */
java_parse_abort_on_error (); java_parse_abort_on_error ();
java_reorder_fields (); /* Reorder the fields */
} }
static int static int
...@@ -893,7 +919,7 @@ parse_zip_file_entries (void) ...@@ -893,7 +919,7 @@ parse_zip_file_entries (void)
continue; continue;
class = lookup_class (get_identifier (ZIPDIR_FILENAME (zdir))); class = lookup_class (get_identifier (ZIPDIR_FILENAME (zdir)));
current_jcf = TYPE_LANG_SPECIFIC (class)->jcf; current_jcf = TYPE_JCF (class);
current_class = class; current_class = class;
if ( !CLASS_LOADED_P (class)) if ( !CLASS_LOADED_P (class))
...@@ -970,9 +996,7 @@ static void process_zip_dir() ...@@ -970,9 +996,7 @@ static void process_zip_dir()
jcf->classname = class_name; jcf->classname = class_name;
jcf->filename = file_name; jcf->filename = file_name;
TYPE_LANG_SPECIFIC (class) = TYPE_JCF (class) = jcf;
(struct lang_type *) perm_calloc (1, sizeof (struct lang_type));
TYPE_LANG_SPECIFIC (class)->jcf = jcf;
} }
} }
...@@ -994,10 +1018,10 @@ DEFUN(find_in_current_zip, (name, length, jcf), ...@@ -994,10 +1018,10 @@ DEFUN(find_in_current_zip, (name, length, jcf),
class = TREE_TYPE (icv); class = TREE_TYPE (icv);
/* Doesn't have jcf specific info ? It's not ours */ /* Doesn't have jcf specific info ? It's not ours */
if (!TYPE_LANG_SPECIFIC (class) || !TYPE_LANG_SPECIFIC (class)->jcf) if (!TYPE_JCF (class))
return 0; return 0;
*jcf = local_jcf = TYPE_LANG_SPECIFIC (class)->jcf; *jcf = local_jcf = TYPE_JCF (class);
fseek (local_jcf->read_state, local_jcf->zip_offset, SEEK_SET); fseek (local_jcf->read_state, local_jcf->zip_offset, SEEK_SET);
return 1; return 1;
} }
......
...@@ -34,6 +34,15 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ ...@@ -34,6 +34,15 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0) #define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
#endif #endif
/* By default, colon separates directories in a path. */
#ifndef PATH_SEPARATOR
#define PATH_SEPARATOR ':'
#endif
#ifndef DIR_SEPARATOR
#define DIR_SEPARATOR '/'
#endif
#ifndef DIR_UP #ifndef DIR_UP
#define DIR_UP ".." #define DIR_UP ".."
#endif #endif
......
...@@ -130,6 +130,14 @@ DEFUN(get_attribute, (jcf), ...@@ -130,6 +130,14 @@ DEFUN(get_attribute, (jcf),
} }
else else
#endif #endif
#ifdef HANDLE_INNERCLASSES_ATTRIBUTE
if (name_length == 12 && memcmp (name_data, "InnerClasses", 12) == 0)
{
uint16 count = JCF_readu2 (jcf);
HANDLE_INNERCLASSES_ATTRIBUTE (count);
}
else
#endif
{ {
#ifdef PROCESS_OTHER_ATTRIBUTE #ifdef PROCESS_OTHER_ATTRIBUTE
PROCESS_OTHER_ATTRIBUTE(jcf, attribute_name, attribute_length); PROCESS_OTHER_ATTRIBUTE(jcf, attribute_name, attribute_length);
......
...@@ -35,6 +35,10 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ ...@@ -35,6 +35,10 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "buffer.h" #include "buffer.h"
#include "toplev.h" #include "toplev.h"
#ifndef DIR_SEPARATOR
#define DIR_SEPARATOR '/'
#endif
extern struct obstack temporary_obstack; extern struct obstack temporary_obstack;
/* Base directory in which `.class' files should be written. /* Base directory in which `.class' files should be written.
...@@ -335,6 +339,9 @@ static void emit_goto PARAMS ((struct jcf_block *, struct jcf_partial *)); ...@@ -335,6 +339,9 @@ static void emit_goto PARAMS ((struct jcf_block *, struct jcf_partial *));
static void emit_jsr PARAMS ((struct jcf_block *, struct jcf_partial *)); static void emit_jsr PARAMS ((struct jcf_block *, struct jcf_partial *));
static void call_cleanups PARAMS ((struct jcf_block *, struct jcf_partial *)); static void call_cleanups PARAMS ((struct jcf_block *, struct jcf_partial *));
static char *make_class_file_name PARAMS ((tree)); static char *make_class_file_name PARAMS ((tree));
static unsigned char *append_synthetic_attribute PARAMS ((struct jcf_partial *));
static void append_innerclasses_attribute PARAMS ((struct jcf_partial *, tree));
static void append_innerclasses_attribute_entry PARAMS ((struct jcf_partial *, tree, tree));
/* Utility macros for appending (big-endian) data to a buffer. /* Utility macros for appending (big-endian) data to a buffer.
We assume a local variable 'ptr' points into where we want to We assume a local variable 'ptr' points into where we want to
...@@ -665,6 +672,11 @@ get_access_flags (decl) ...@@ -665,6 +672,11 @@ get_access_flags (decl)
flags |= ACC_ABSTRACT; flags |= ACC_ABSTRACT;
if (CLASS_INTERFACE (decl)) if (CLASS_INTERFACE (decl))
flags |= ACC_INTERFACE; flags |= ACC_INTERFACE;
if (CLASS_STATIC (decl))
flags |= ACC_STATIC;
if (ANONYMOUS_CLASS_P (TREE_TYPE (decl))
|| LOCAL_CLASS_P (TREE_TYPE (decl)))
flags |= ACC_PRIVATE;
} }
else else
fatal ("internal error - bad argument to get_access_flags"); fatal ("internal error - bad argument to get_access_flags");
...@@ -1159,8 +1171,7 @@ generate_bytecode_conditional (exp, true_label, false_label, ...@@ -1159,8 +1171,7 @@ generate_bytecode_conditional (exp, true_label, false_label,
} }
break; break;
case TRUTH_NOT_EXPR: case TRUTH_NOT_EXPR:
generate_bytecode_conditional (TREE_OPERAND (exp, 0), generate_bytecode_conditional (TREE_OPERAND (exp, 0), false_label, true_label,
false_label, true_label,
! true_branch_first, state); ! true_branch_first, state);
break; break;
case TRUTH_ANDIF_EXPR: case TRUTH_ANDIF_EXPR:
...@@ -1238,7 +1249,7 @@ generate_bytecode_conditional (exp, true_label, false_label, ...@@ -1238,7 +1249,7 @@ generate_bytecode_conditional (exp, true_label, false_label,
} }
if (integer_zerop (exp1) || integer_zerop (exp0)) if (integer_zerop (exp1) || integer_zerop (exp0))
{ {
generate_bytecode_insns (integer_zerop (exp1) ? exp0 : exp1, generate_bytecode_insns (integer_zerop (exp1) ? exp0 : exp0,
STACK_TARGET, state); STACK_TARGET, state);
op = op + (OPCODE_ifnull - OPCODE_if_acmpeq); op = op + (OPCODE_ifnull - OPCODE_if_acmpeq);
negop = (op & 1) ? op - 1 : op + 1; negop = (op & 1) ? op - 1 : op + 1;
...@@ -1622,7 +1633,6 @@ generate_bytecode_insns (exp, target, state) ...@@ -1622,7 +1633,6 @@ generate_bytecode_insns (exp, target, state)
define_jcf_label (else_label, state); define_jcf_label (else_label, state);
generate_bytecode_insns (TREE_OPERAND (exp, 2), target, state); generate_bytecode_insns (TREE_OPERAND (exp, 2), target, state);
define_jcf_label (end_label, state); define_jcf_label (end_label, state);
/* COND_EXPR can be used in a binop. The stack must be adjusted. */ /* COND_EXPR can be used in a binop. The stack must be adjusted. */
if (TREE_TYPE (exp) != void_type_node) if (TREE_TYPE (exp) != void_type_node)
NOTE_POP (TYPE_IS_WIDE (TREE_TYPE (exp)) ? 2 : 1); NOTE_POP (TYPE_IS_WIDE (TREE_TYPE (exp)) ? 2 : 1);
...@@ -2131,6 +2141,9 @@ generate_bytecode_insns (exp, target, state) ...@@ -2131,6 +2141,9 @@ generate_bytecode_insns (exp, target, state)
OP2 (index); OP2 (index);
} }
break; break;
case SAVE_EXPR:
generate_bytecode_insns (TREE_OPERAND (exp, 0), STACK_TARGET, state);
break;
case CONVERT_EXPR: case CONVERT_EXPR:
case NOP_EXPR: case NOP_EXPR:
case FLOAT_EXPR: case FLOAT_EXPR:
...@@ -2535,11 +2548,6 @@ generate_bytecode_insns (exp, target, state) ...@@ -2535,11 +2548,6 @@ generate_bytecode_insns (exp, target, state)
else else
OP1 (OPCODE_invokevirtual); OP1 (OPCODE_invokevirtual);
OP2 (index); OP2 (index);
if (interface)
{
OP1 (nargs);
OP1 (0);
}
f = TREE_TYPE (TREE_TYPE (f)); f = TREE_TYPE (TREE_TYPE (f));
if (TREE_CODE (f) != VOID_TYPE) if (TREE_CODE (f) != VOID_TYPE)
{ {
...@@ -2549,6 +2557,11 @@ generate_bytecode_insns (exp, target, state) ...@@ -2549,6 +2557,11 @@ generate_bytecode_insns (exp, target, state)
else else
NOTE_PUSH (size); NOTE_PUSH (size);
} }
if (interface)
{
OP1 (nargs);
OP1 (0);
}
break; break;
} }
} }
...@@ -2836,16 +2849,24 @@ generate_classfile (clas, state) ...@@ -2836,16 +2849,24 @@ generate_classfile (clas, state)
for (part = TYPE_FIELDS (clas); part; part = TREE_CHAIN (part)) for (part = TYPE_FIELDS (clas); part; part = TREE_CHAIN (part))
{ {
int have_value; int have_value, attr_count = 0;
if (DECL_NAME (part) == NULL_TREE || DECL_ARTIFICIAL (part)) if (DECL_NAME (part) == NULL_TREE || DECL_ARTIFICIAL (part))
continue; continue;
ptr = append_chunk (NULL, 8, state); ptr = append_chunk (NULL, 8, state);
i = get_access_flags (part); PUT2 (i); i = get_access_flags (part); PUT2 (i);
i = find_utf8_constant (&state->cpool, DECL_NAME (part)); PUT2 (i); i = find_utf8_constant (&state->cpool, DECL_NAME (part)); PUT2 (i);
i = find_utf8_constant (&state->cpool, build_java_signature (TREE_TYPE (part))); i = find_utf8_constant (&state->cpool,
build_java_signature (TREE_TYPE (part)));
PUT2(i); PUT2(i);
have_value = DECL_INITIAL (part) != NULL_TREE && FIELD_STATIC (part); have_value = DECL_INITIAL (part) != NULL_TREE && FIELD_STATIC (part)
PUT2 (have_value); /* attributes_count */ && TREE_CODE (TREE_TYPE (part)) != POINTER_TYPE;
if (have_value)
attr_count++;
if (FIELD_THISN (part) || FIELD_LOCAL_ALIAS (part))
attr_count++;
PUT2 (attr_count); /* attributes_count */
if (have_value) if (have_value)
{ {
tree init = DECL_INITIAL (part); tree init = DECL_INITIAL (part);
...@@ -2858,6 +2879,9 @@ generate_classfile (clas, state) ...@@ -2858,6 +2879,9 @@ generate_classfile (clas, state)
PUT4 (2); /* attribute_length */ PUT4 (2); /* attribute_length */
i = find_constant_index (init, state); PUT2 (i); i = find_constant_index (init, state); PUT2 (i);
} }
/* Emit the "Synthetic" attribute for val$<x> and this$<n> fields. */
if (FIELD_THISN (part) || FIELD_LOCAL_ALIAS (part))
ptr = append_synthetic_attribute (state);
fields_count++; fields_count++;
} }
ptr = fields_count_ptr; UNSAFE_PUT2 (fields_count); ptr = fields_count_ptr; UNSAFE_PUT2 (fields_count);
...@@ -2875,6 +2899,7 @@ generate_classfile (clas, state) ...@@ -2875,6 +2899,7 @@ generate_classfile (clas, state)
: DECL_NAME (part); : DECL_NAME (part);
tree type = TREE_TYPE (part); tree type = TREE_TYPE (part);
tree save_function = current_function_decl; tree save_function = current_function_decl;
int synthetic_p = 0;
current_function_decl = part; current_function_decl = part;
ptr = append_chunk (NULL, 8, state); ptr = append_chunk (NULL, 8, state);
i = get_access_flags (part); PUT2 (i); i = get_access_flags (part); PUT2 (i);
...@@ -2882,7 +2907,20 @@ generate_classfile (clas, state) ...@@ -2882,7 +2907,20 @@ generate_classfile (clas, state)
i = find_utf8_constant (&state->cpool, build_java_signature (type)); i = find_utf8_constant (&state->cpool, build_java_signature (type));
PUT2 (i); PUT2 (i);
i = (body != NULL_TREE) + (DECL_FUNCTION_THROWS (part) != NULL_TREE); i = (body != NULL_TREE) + (DECL_FUNCTION_THROWS (part) != NULL_TREE);
/* Make room for the Synthetic attribute (of zero length.) */
if (DECL_FINIT_P (part)
|| OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (part)))
{
i++;
synthetic_p = 1;
}
PUT2 (i); /* attributes_count */ PUT2 (i); /* attributes_count */
if (synthetic_p)
ptr = append_synthetic_attribute (state);
if (body != NULL_TREE) if (body != NULL_TREE)
{ {
int code_attributes_count = 0; int code_attributes_count = 0;
...@@ -2956,7 +2994,8 @@ generate_classfile (clas, state) ...@@ -2956,7 +2994,8 @@ generate_classfile (clas, state)
if (state->linenumber_count > 0) if (state->linenumber_count > 0)
{ {
static tree LineNumberTable_node = NULL_TREE; static tree LineNumberTable_node = NULL_TREE;
ptr = append_chunk (NULL, 8 + 4 * state->linenumber_count, state); ptr = append_chunk (NULL,
8 + 4 * state->linenumber_count, state);
if (LineNumberTable_node == NULL_TREE) if (LineNumberTable_node == NULL_TREE)
LineNumberTable_node = get_identifier ("LineNumberTable"); LineNumberTable_node = get_identifier ("LineNumberTable");
i = find_utf8_constant (&state->cpool, LineNumberTable_node); i = find_utf8_constant (&state->cpool, LineNumberTable_node);
...@@ -3031,7 +3070,10 @@ generate_classfile (clas, state) ...@@ -3031,7 +3070,10 @@ generate_classfile (clas, state)
source_file = ptr+1; source_file = ptr+1;
} }
ptr = append_chunk (NULL, 10, state); ptr = append_chunk (NULL, 10, state);
PUT2 (1); /* attributes_count */
i = ((INNER_CLASS_TYPE_P (clas)
|| DECL_INNER_CLASS_LIST (TYPE_NAME (clas))) ? 2 : 1);
PUT2 (i); /* attributes_count */
/* generate the SourceFile attribute. */ /* generate the SourceFile attribute. */
if (SourceFile_node == NULL_TREE) if (SourceFile_node == NULL_TREE)
...@@ -3041,6 +3083,7 @@ generate_classfile (clas, state) ...@@ -3041,6 +3083,7 @@ generate_classfile (clas, state)
PUT4 (2); PUT4 (2);
i = find_utf8_constant (&state->cpool, get_identifier (source_file)); i = find_utf8_constant (&state->cpool, get_identifier (source_file));
PUT2 (i); PUT2 (i);
append_innerclasses_attribute (state, clas);
/* New finally generate the contents of the constant pool chunk. */ /* New finally generate the contents of the constant pool chunk. */
i = count_constant_pool_bytes (&state->cpool); i = count_constant_pool_bytes (&state->cpool);
...@@ -3051,6 +3094,103 @@ generate_classfile (clas, state) ...@@ -3051,6 +3094,103 @@ generate_classfile (clas, state)
return state->first; return state->first;
} }
static unsigned char *
append_synthetic_attribute (state)
struct jcf_partial *state;
{
static tree Synthetic_node = NULL_TREE;
unsigned char *ptr = append_chunk (NULL, 6, state);
int i;
if (Synthetic_node == NULL_TREE)
Synthetic_node = get_identifier ("Synthetic");
i = find_utf8_constant (&state->cpool, Synthetic_node);
PUT2 (i); /* Attribute string index */
PUT4 (0); /* Attribute length */
return ptr;
}
static void
append_innerclasses_attribute (state, class)
struct jcf_partial *state;
tree class;
{
static tree InnerClasses_node = NULL_TREE;
tree orig_decl = TYPE_NAME (class);
tree current, decl;
int length = 0, i;
unsigned char *ptr, *length_marker, *number_marker;
if (!INNER_CLASS_TYPE_P (class) && !DECL_INNER_CLASS_LIST (orig_decl))
return;
ptr = append_chunk (NULL, 8, state); /* 2+4+2 */
if (InnerClasses_node == NULL_TREE)
InnerClasses_node = get_identifier ("InnerClasses");
i = find_utf8_constant (&state->cpool, InnerClasses_node);
PUT2 (i);
length_marker = ptr; PUT4 (0); /* length, to be later patched */
number_marker = ptr; PUT2 (0); /* number of classes, tblp */
/* Generate the entries: all inner classes visible from the one we
process: itself, up and down. */
while (class && INNER_CLASS_TYPE_P (class))
{
char *n;
decl = TYPE_NAME (class);
n = IDENTIFIER_POINTER (DECL_NAME (decl)) +
IDENTIFIER_LENGTH (DECL_NAME (decl));
while (n[-1] != '$')
n--;
append_innerclasses_attribute_entry (state, decl, get_identifier (n));
length++;
class = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class)));
}
decl = orig_decl;
for (current = DECL_INNER_CLASS_LIST (decl);
current; current = TREE_CHAIN (current))
{
append_innerclasses_attribute_entry (state, TREE_PURPOSE (current),
TREE_VALUE (current));
length++;
}
ptr = length_marker; PUT4 (8*length+2);
ptr = number_marker; PUT2 (length);
}
static void
append_innerclasses_attribute_entry (state, decl, name)
struct jcf_partial *state;
tree decl, name;
{
static tree anonymous_name = NULL_TREE;
int icii, ocii, ini, icaf;
unsigned char *ptr = append_chunk (NULL, 8, state);
if (!anonymous_name)
anonymous_name = get_identifier ("");
icii = find_class_constant (&state->cpool, TREE_TYPE (decl));
ocii = find_class_constant (&state->cpool, TREE_TYPE (DECL_CONTEXT (decl)));
/* The specs are saying that if the class is anonymous,
inner_name_index must be zero. But the implementation makes it
point to an empty string. */
ini = find_utf8_constant (&state->cpool,
(ANONYMOUS_CLASS_P (TREE_TYPE (decl)) ?
anonymous_name : name));
icaf = get_access_flags (decl);
PUT2 (icii); PUT2 (ocii); PUT2 (ini); PUT2 (icaf);
}
static char * static char *
make_class_file_name (clas) make_class_file_name (clas)
tree clas; tree clas;
......
...@@ -413,7 +413,7 @@ put_decl_node (node) ...@@ -413,7 +413,7 @@ put_decl_node (node)
} }
#endif #endif
if (TREE_CODE (node) == FUNCTION_DECL if (TREE_CODE (node) == FUNCTION_DECL
&& DECL_NAME (node) == init_identifier_node && DECL_INIT_P (node)
&& !DECL_ARTIFICIAL (node) && current_class) && !DECL_ARTIFICIAL (node) && current_class)
put_decl_node (TYPE_NAME (current_class)); put_decl_node (TYPE_NAME (current_class));
else else
......
...@@ -72,6 +72,10 @@ java_init_lex () ...@@ -72,6 +72,10 @@ java_init_lex ()
java_lang_id = get_identifier ("java.lang"); java_lang_id = get_identifier ("java.lang");
if (!java_lang_cloneable) if (!java_lang_cloneable)
java_lang_cloneable = get_identifier ("java.lang.Cloneable"); java_lang_cloneable = get_identifier ("java.lang.Cloneable");
if (!inst_id)
inst_id = get_identifier ("inst$");
if (!wpv_id)
wpv_id = get_identifier ("write_parm_value$");
if (!java_lang_imported) if (!java_lang_imported)
{ {
...@@ -95,9 +99,9 @@ java_init_lex () ...@@ -95,9 +99,9 @@ java_init_lex ()
if (!wfl_to_string) if (!wfl_to_string)
wfl_to_string = build_expr_wfl (get_identifier ("toString"), NULL, 0, 0); wfl_to_string = build_expr_wfl (get_identifier ("toString"), NULL, 0, 0);
ctxp->static_initialized = ctxp->non_static_initialized = CPC_INITIALIZER_LIST (ctxp) = CPC_STATIC_INITIALIZER_LIST (ctxp) =
ctxp->incomplete_class = NULL_TREE; CPC_INSTANCE_INITIALIZER_LIST (ctxp) = ctxp->incomplete_class = NULL_TREE;
bzero ((PTR) ctxp->modifier_ctx, 11*sizeof (ctxp->modifier_ctx[0])); bzero ((PTR) ctxp->modifier_ctx, 11*sizeof (ctxp->modifier_ctx[0]));
bzero ((PTR) current_jcf, sizeof (JCF)); bzero ((PTR) current_jcf, sizeof (JCF));
ctxp->current_parsed_class = NULL; ctxp->current_parsed_class = NULL;
......
...@@ -56,7 +56,7 @@ unicode_mangling_length (name, len) ...@@ -56,7 +56,7 @@ unicode_mangling_length (name, len)
need_escapes += num_chars == 0; need_escapes += num_chars == 0;
else if (ch == '_') else if (ch == '_')
underscores++; underscores++;
else if ((ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z')) else if (ch != '$' && (ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z'))
need_escapes++; need_escapes++;
num_chars++; num_chars++;
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -611,12 +611,8 @@ build_java_signature (type) ...@@ -611,12 +611,8 @@ build_java_signature (type)
push_obstacks (&permanent_obstack, &permanent_obstack); push_obstacks (&permanent_obstack, &permanent_obstack);
while (TREE_CODE (type) == POINTER_TYPE) while (TREE_CODE (type) == POINTER_TYPE)
type = TREE_TYPE (type); type = TREE_TYPE (type);
if (TYPE_LANG_SPECIFIC (type) == NULL) MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC (type);
{ sig = TYPE_SIGNATURE (type);
TYPE_LANG_SPECIFIC (type) = (struct lang_type *)
perm_calloc (1, sizeof (struct lang_type));
}
sig = TYPE_LANG_SPECIFIC (type)->signature;
if (sig == NULL_TREE) if (sig == NULL_TREE)
{ {
char sg[2]; char sg[2];
...@@ -682,7 +678,7 @@ build_java_signature (type) ...@@ -682,7 +678,7 @@ build_java_signature (type)
default: default:
fatal ("internal error - build_java_signature passed invalid type"); fatal ("internal error - build_java_signature passed invalid type");
} }
TYPE_LANG_SPECIFIC (type)->signature = sig; TYPE_SIGNATURE (type) = sig;
} }
pop_obstacks (); pop_obstacks ();
return sig; return sig;
...@@ -698,16 +694,11 @@ set_java_signature (type, sig) ...@@ -698,16 +694,11 @@ set_java_signature (type, sig)
tree old_sig; tree old_sig;
while (TREE_CODE (type) == POINTER_TYPE) while (TREE_CODE (type) == POINTER_TYPE)
type = TREE_TYPE (type); type = TREE_TYPE (type);
if (TYPE_LANG_SPECIFIC (type) == NULL) MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC (type);
{ old_sig = TYPE_SIGNATURE (type);
TYPE_LANG_SPECIFIC (type) = (struct lang_type *)
perm_calloc (1, sizeof (struct lang_type));
}
old_sig = TYPE_LANG_SPECIFIC (type)->signature;
if (old_sig != NULL_TREE && old_sig != sig) if (old_sig != NULL_TREE && old_sig != sig)
fatal ("internal error - set_java_signature"); fatal ("internal error - set_java_signature");
TYPE_LANG_SPECIFIC (type)->signature = sig; TYPE_SIGNATURE (type) = sig;
#if 0 /* careful about METHOD_TYPE */ #if 0 /* careful about METHOD_TYPE */
if (IDENTIFIER_SIGNATURE_TYPE (sig) == NULL_TREE && TREE_PERMANENT (type)) if (IDENTIFIER_SIGNATURE_TYPE (sig) == NULL_TREE && TREE_PERMANENT (type))
IDENTIFIER_SIGNATURE_TYPE (sig) = type; IDENTIFIER_SIGNATURE_TYPE (sig) = type;
......
...@@ -940,11 +940,10 @@ verify_jvm_instructions (jcf, byte_ops, length) ...@@ -940,11 +940,10 @@ verify_jvm_instructions (jcf, byte_ops, length)
pop_argument_types (TYPE_ARG_TYPES (method_type)); pop_argument_types (TYPE_ARG_TYPES (method_type));
/* Can't invoke <clinit> */ /* Can't invoke <clinit> */
if (method_name == clinit_identifier_node) if (ID_CLINIT_P (method_name))
VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>"); VERIFICATION_ERROR ("invoke opcode can't invoke <clinit>");
/* Apart invokespecial, can't invoke <init> */ /* Apart invokespecial, can't invoke <init> */
if (op_code != OPCODE_invokespecial if (op_code != OPCODE_invokespecial && ID_INIT_P (method_name))
&& method_name == init_identifier_node)
VERIFICATION_ERROR ("invoke opcode can't invoke <init>"); VERIFICATION_ERROR ("invoke opcode can't invoke <init>");
if (op_code != OPCODE_invokestatic) if (op_code != OPCODE_invokestatic)
......
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