aboutsummaryrefslogtreecommitdiff
path: root/gcc/java/jcf-write.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/java/jcf-write.c')
-rw-r--r--gcc/java/jcf-write.c59
1 files changed, 40 insertions, 19 deletions
diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c
index 33ad106..6211cf9 100644
--- a/gcc/java/jcf-write.c
+++ b/gcc/java/jcf-write.c
@@ -410,7 +410,13 @@ put_linenumber (line, state)
int line;
struct jcf_partial *state;
{
- (get_jcf_label_here (state))->linenumber = line;
+ struct jcf_block *label = get_jcf_label_here (state);
+ if (label->linenumber > 0)
+ {
+ label = gen_jcf_label (state);
+ define_jcf_label (label, state);
+ }
+ label->linenumber = line;
state->linenumber_count++;
}
@@ -1276,12 +1282,15 @@ generate_bytecode_insns (exp, target, state)
case EXPR_WITH_FILE_LOCATION:
{
char *saved_input_filename = input_filename;
+ tree body = EXPR_WFL_NODE (exp);
int saved_lineno = lineno;
+ if (body == empty_stmt_node)
+ break;
input_filename = EXPR_WFL_FILENAME (exp);
lineno = EXPR_WFL_LINENO (exp);
- if (EXPR_WFL_EMIT_LINE_NOTE (exp))
- put_linenumber (EXPR_WFL_LINENO (exp), state);
- generate_bytecode_insns (EXPR_WFL_NODE (exp), target, state);
+ if (EXPR_WFL_EMIT_LINE_NOTE (exp) && lineno > 0)
+ put_linenumber (lineno, state);
+ generate_bytecode_insns (body, target, state);
input_filename = saved_input_filename;
lineno = saved_lineno;
}
@@ -1703,7 +1712,7 @@ generate_bytecode_insns (exp, target, state)
emit_dup (1, 0, state);
/* Stack: ..., objectref, objectref. */
field_op (TREE_OPERAND (exp, 1), OPCODE_getfield, state);
- NOTE_PUSH (size);
+ NOTE_PUSH (size-1);
/* Stack: ..., objectref, oldvalue. */
offset = 1;
}
@@ -1742,7 +1751,9 @@ generate_bytecode_insns (exp, target, state)
emit_binop (OPCODE_iadd + adjust_typed_op (type, 3), type, state);
if (target != IGNORE_TARGET && ! post_op)
emit_dup (size, offset, state);
- /* Stack: ..., [result,] newvalue. */
+ /* Stack, if ARRAY_REF: ..., [result, ] array, index, newvalue. */
+ /* Stack, if COMPONENT_REF: ..., [result, ] objectref, newvalue. */
+ /* Stack, otherwise: ..., [result, ] newvalue. */
goto finish_assignment;
case MODIFY_EXPR:
@@ -1817,11 +1828,10 @@ generate_bytecode_insns (exp, target, state)
if (! FIELD_STATIC (field))
NOTE_POP (1);
field_op (field,
- FIELD_STATIC (field) ? OPCODE_putstatic
- : OPCODE_putfield,
+ FIELD_STATIC (field) ? OPCODE_putstatic : OPCODE_putfield,
state);
- NOTE_PUSH (TYPE_IS_WIDE (TREE_TYPE (field)) ? 2 : 1);
+ NOTE_POP (TYPE_IS_WIDE (TREE_TYPE (field)) ? 2 : 1);
}
else if (TREE_CODE (exp) == VAR_DECL
|| TREE_CODE (exp) == PARM_DECL)
@@ -1829,18 +1839,17 @@ generate_bytecode_insns (exp, target, state)
if (FIELD_STATIC (exp))
{
field_op (exp, OPCODE_putstatic, state);
- NOTE_PUSH (TYPE_IS_WIDE (TREE_TYPE (exp)) ? 2 : 1);
+ NOTE_POP (TYPE_IS_WIDE (TREE_TYPE (exp)) ? 2 : 1);
}
else
emit_store (exp, state);
}
else if (TREE_CODE (exp) == ARRAY_REF)
{
- NOTE_POP (2);
jopcode = OPCODE_iastore + adjust_typed_op (TREE_TYPE (exp), 7);
RESERVE(1);
OP1 (jopcode);
- NOTE_PUSH (TYPE_IS_WIDE (TREE_TYPE (exp)) ? 2 : 1);
+ NOTE_POP (TYPE_IS_WIDE (TREE_TYPE (exp)) ? 4 : 3);
}
else
fatal ("internal error (bad lhs to MODIFY_EXPR)");
@@ -1883,8 +1892,11 @@ generate_bytecode_insns (exp, target, state)
generate_bytecode_insns (arg0, target, state);
generate_bytecode_insns (arg1, target, state);
}
+ /* For most binary operations, both operands and the result have the
+ same type. Shift operations are different. Using arg1's type
+ gets us the correct SP adjustment in all casesd. */
if (target == STACK_TARGET)
- emit_binop (jopcode, type, state);
+ emit_binop (jopcode, TREE_TYPE (arg1), state);
break;
}
case TRUTH_NOT_EXPR:
@@ -2054,10 +2066,16 @@ generate_bytecode_insns (exp, target, state)
break;
case NEW_ARRAY_INIT:
{
- tree values;
+ tree values = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0));
tree array_type = TREE_TYPE (TREE_TYPE (exp));
tree element_type = TYPE_ARRAY_ELEMENT (array_type);
HOST_WIDE_INT length = java_array_type_length (array_type);
+ if (target == IGNORE_TARGET)
+ {
+ for ( ; values != NULL_TREE; values = TREE_CHAIN (values))
+ generate_bytecode_insns (TREE_VALUE (values), target, state);
+ break;
+ }
push_int_const (length, state);
NOTE_PUSH (1);
RESERVE (3);
@@ -2074,7 +2092,6 @@ generate_bytecode_insns (exp, target, state)
OP1 (OPCODE_anewarray);
OP2 (index);
}
- values = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0));
offset = 0;
jopcode = OPCODE_iastore + adjust_typed_op (element_type, 7);
for ( ; values != NULL_TREE; values = TREE_CHAIN (values), offset++)
@@ -2082,6 +2099,7 @@ generate_bytecode_insns (exp, target, state)
int save_SP = state->code_SP;
emit_dup (1, 0, state);
push_int_const (offset, state);
+ NOTE_PUSH (1);
generate_bytecode_insns (TREE_VALUE (values), STACK_TARGET, state);
RESERVE (1);
OP1 (jopcode);
@@ -2183,11 +2201,11 @@ generate_bytecode_insns (exp, target, state)
int index = find_methodref_index (&state->cpool, f);
int interface = 0;
RESERVE (5);
- if (DECL_CONSTRUCTOR_P (f) || CALL_USING_SUPER (exp)
+ if (METHOD_STATIC (f))
+ OP1 (OPCODE_invokestatic);
+ else if (DECL_CONSTRUCTOR_P (f) || CALL_USING_SUPER (exp)
|| METHOD_PRIVATE (f))
OP1 (OPCODE_invokespecial);
- else if (METHOD_STATIC (f))
- OP1 (OPCODE_invokestatic);
else if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (f))))
{
OP1 (OPCODE_invokeinterface);
@@ -2496,7 +2514,7 @@ generate_classfile (clas, state)
for (part = TYPE_FIELDS (clas); part; part = TREE_CHAIN (part))
{
int have_value;
- if (DECL_NAME (part) == NULL_TREE)
+ if (DECL_NAME (part) == NULL_TREE || DECL_ARTIFICIAL (part))
continue;
ptr = append_chunk (NULL, 8, state);
i = get_access_flags (part); PUT2 (i);
@@ -2533,6 +2551,8 @@ generate_classfile (clas, state)
tree name = DECL_CONSTRUCTOR_P (part) ? init_identifier_node
: DECL_NAME (part);
tree type = TREE_TYPE (part);
+ tree save_function = current_function_decl;
+ current_function_decl = part;
ptr = append_chunk (NULL, 8, state);
i = get_access_flags (part); PUT2 (i);
i = find_utf8_constant (&state->cpool, name); PUT2 (i);
@@ -2653,6 +2673,7 @@ generate_classfile (clas, state)
}
}
methods_count++;
+ current_function_decl = save_function;
}
ptr = methods_count_ptr; PUT2 (methods_count);