#include "c-lang.h"
#include "jv-lang.h"
#include "gdbcore.h"
+#include <ctype.h>
struct type *java_int_type;
struct type *java_byte_type;
obstack_alloc (&dynamics_objfile->symbol_obstack, sizeof (struct symbol));
memset (sym, 0, sizeof (struct symbol));
SYMBOL_LANGUAGE (sym) = language_java;
- SYMBOL_NAME (sym) = TYPE_NAME (type);
+ SYMBOL_NAME (sym) = TYPE_TAG_NAME (type);
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
/* SYMBOL_VALUE (sym) = valu;*/
SYMBOL_TYPE (sym) = type;
type = alloc_type (objfile);
TYPE_CODE (type) = TYPE_CODE_STRUCT;
INIT_CPLUS_SPECIFIC (type);
- TYPE_NAME (type) = obsavestring (name, strlen(name), &objfile->type_obstack);
+ TYPE_TAG_NAME (type) = obsavestring (name, strlen(name), &objfile->type_obstack);
TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
TYPE ? = addr;
return type;
{
char *chrs;
value_ptr temp = name;
- int name_length = (int) value_as_long
- (value_struct_elt (&temp, NULL, "length", NULL, "structure"));
- temp = name;
- temp = value_struct_elt (&temp, NULL, "data", NULL, "structure");
+ int name_length;
+ CORE_ADDR data_addr;
+ temp = value_struct_elt (&temp, NULL, "length", NULL, "structure");
+ name_length = (int) value_as_long (temp);
+ data_addr = VALUE_ADDRESS (temp) + VALUE_OFFSET (temp)
+ + TYPE_LENGTH (VALUE_TYPE (temp));
chrs = obstack_alloc (obstack, name_length+1);
chrs [name_length] = '\0';
- read_memory_section (VALUE_ADDRESS (temp) + VALUE_OFFSET (temp),
- chrs, name_length, NULL);
+ read_memory_section (data_addr, chrs, name_length, NULL);
return chrs;
}
java_class_from_object (obj_val)
value_ptr obj_val;
{
- value_ptr dtable_val = value_struct_elt (&obj_val, NULL, "dtable", NULL, "structure");
+ /* This is all rather inefficient, since the offsets of dtable and
+ class are fixed. FIXME */
+ value_ptr dtable_val;
+
+ if (TYPE_CODE (VALUE_TYPE (obj_val)) == TYPE_CODE_PTR
+ && TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (obj_val))) == 0)
+ {
+ struct symbol *sym;
+ sym = lookup_symbol ("Hjava_lang_Object", NULL, STRUCT_NAMESPACE,
+ (int *) 0, (struct symtab **) NULL);
+ if (sym != NULL)
+ obj_val = value_at (VALUE_TYPE (sym),
+ value_as_pointer (obj_val), NULL);
+ }
+
+ dtable_val = value_struct_elt (&obj_val, NULL, "dtable", NULL, "structure");
return value_struct_elt (&dtable_val, NULL, "class", NULL, "structure");
}
struct type *type;
char *name;
value_ptr temp;
- struct objfile *objfile = get_dynamics_objfile();
+ struct objfile *objfile;
value_ptr utf8_name;
char *nptr;
CORE_ADDR addr;
}
addr = VALUE_ADDRESS (clas) + VALUE_OFFSET (clas);
+#if 0
get_java_class_symtab ();
bl = BLOCKVECTOR_BLOCK (BLOCKVECTOR (class_symtab), GLOBAL_BLOCK);
for (i = BLOCK_NSYMS (bl); --i >= 0; )
if (SYMBOL_VALUE_ADDRESS (sym) == addr)
return SYMBOL_TYPE (sym);
}
+#endif
+ objfile = get_dynamics_objfile();
if (java_class_is_primitive (clas))
{
value_ptr sig;
temp = clas;
utf8_name = value_struct_elt (&temp, NULL, "name", NULL, "structure");
name = get_java_utf8_name (&objfile->type_obstack, utf8_name);
+ for (nptr = name; *nptr != 0; nptr++)
+ {
+ if (*nptr == '/')
+ *nptr = '.';
+ }
+
+ type = java_lookup_class (name);
+ if (type != NULL)
+ return type;
type = alloc_type (objfile);
TYPE_CODE (type) = TYPE_CODE_STRUCT;
VALUE_TYPE (temp) = lookup_pointer_type (VALUE_TYPE (clas));
TYPE_TARGET_TYPE (type) = type_from_class (temp);
}
- for (nptr = name; *nptr != 0; nptr++)
- {
- if (*nptr == '/')
- *nptr = '.';
- }
ALLOCATE_CPLUS_STRUCT_TYPE (type);
- TYPE_NAME (type) = name;
+ TYPE_TAG_NAME (type) = name;
add_class_symtab_symbol (add_class_symbol (type, addr));
return java_link_class_type (type, clas);
{
value_ptr temp;
char *unqualified_name;
- char *name = TYPE_NAME (type);
+ char *name = TYPE_TAG_NAME (type);
int ninterfaces, nfields, nmethods;
int type_is_object = 0;
struct fn_field *fn_fields;
temp = clas;
nfields = value_as_long (value_struct_elt (&temp, NULL, "nfields", NULL, "structure"));
nfields += TYPE_N_BASECLASSES (type);
+ nfields++; /* Add one for dummy "class" field. */
TYPE_NFIELDS (type) = nfields;
TYPE_FIELDS (type) = (struct field *)
TYPE_ALLOC (type, sizeof (struct field) * nfields);
}
- temp = clas;
- temp = value_struct_elt (&temp, NULL, "bfsize", NULL, "structure");
- TYPE_LENGTH (type) = JAVA_OBJECT_SIZE + value_as_long (temp);
+ if (name[0] == '[' && tsuper != NULL)
+ {
+ TYPE_LENGTH (type) = TYPE_LENGTH (tsuper) + 4; /* size with "length" */
+ }
+ else
+ {
+ temp = clas;
+ temp = value_struct_elt (&temp, NULL, "bfsize", NULL, "structure");
+ TYPE_LENGTH (type) = value_as_long (temp);
+ }
fields = NULL;
+ nfields--; /* First set up dummy "class" field. */
+ SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields),
+ VALUE_ADDRESS (clas) + VALUE_OFFSET (clas));
+ TYPE_FIELD_NAME (type, nfields) = "class";
+ TYPE_FIELD_TYPE (type, nfields) = VALUE_TYPE (clas);
+ SET_TYPE_FIELD_PRIVATE (type, nfields);
+
for (i = TYPE_N_BASECLASSES (type); i < nfields; i++)
{
int accflags;
temp = field;
accflags = value_as_long (value_struct_elt (&temp, NULL, "accflags",
NULL, "structure"));
+ temp = field;
+ temp = value_struct_elt (&temp, NULL, "info", NULL, "structure");
boffset = value_as_long (value_struct_elt (&temp, NULL, "boffset",
NULL, "structure"));
if (accflags & 0x0001) /* public access */
SET_TYPE_FIELD_PROTECTED (type, i);
}
if (accflags & 0x0008) /* ACC_STATIC */
- {
- TYPE_FIELD_BITPOS (type, i) = -1;
- /* Hack for TYPE_FIELD_STATIC_PHYSNAME to prevent a crash. FIXME. */
- type->fields[i].bitsize = (long) "???";
- }
+ SET_FIELD_PHYSADDR(TYPE_FIELD(type, i), boffset);
else
- TYPE_FIELD_BITPOS (type, i) = 8 * (JAVA_OBJECT_SIZE + boffset);
+ TYPE_FIELD_BITPOS (type, i) = 8 * boffset;
if (accflags & 0x8000) /* FIELD_UNRESOLVED_FLAG */
{
TYPE_FIELD_TYPE (type, i) = get_java_object_type (); /* FIXME */
return 0;
while (TYPE_N_BASECLASSES (ttype) > 0)
ttype = TYPE_BASECLASS (ttype, 0);
- name = TYPE_NAME (ttype);
+ name = TYPE_TAG_NAME (ttype);
if (name != NULL && strcmp (name, "java.lang.Object") == 0)
return 1;
name = TYPE_NFIELDS (ttype) > 0 ? TYPE_FIELD_NAME (ttype, 0) : (char*)0;
error ("unknown signature '%c' for primitive type", (char) signature);
}
+/* Return the demangled name of the Java type signature string SIGNATURE,
+ as a freshly allocated copy. */
+
+char *
+java_demangle_type_signature (signature)
+ char *signature;
+{
+ int array = 0;
+ char *result;
+ char *ptr;
+ int i;
+ while (*signature == '[')
+ {
+ array++;
+ signature++;
+ }
+ switch (signature[0])
+ {
+ case 'L':
+ /* Substract 2 for 'L' and ';', but add 1 for final nul. */
+ result = xmalloc (strlen (signature) - 1 + 2 * array);
+ signature++;
+ ptr = result;
+ for ( ; *signature != ';' && *signature != '\0'; signature++)
+ {
+ if (*signature == '/')
+ *ptr++ = '.';
+ else
+ *ptr++ = *signature;
+ }
+ break;
+ default:
+ ptr = TYPE_NAME (java_primitive_type (signature[0]));
+ i = strlen (ptr);
+ result = xmalloc (i + 1 + 2 * array);
+ strcpy (result, ptr);
+ ptr = result + i;
+ break;
+ }
+ while (--array >= 0)
+ {
+ *ptr++ = '[';
+ *ptr++ = ']';
+ }
+ *ptr = '\0';
+ return result;
+}
+
+struct type *
+java_lookup_type (signature)
+ char *signature;
+{
+ switch (signature[0])
+ {
+ case 'L':
+ case '[':
+ error ("java_lookup_type not fully inmplemented");
+ default:
+ return java_primitive_type (signature[0]);
+ }
+}
+
/* Return the type of TYPE followed by DIMS pairs of [ ].
If DIMS == 0, TYPE is returned. */
struct type *type;
int dims;
{
- if (dims == 0)
- return type;
- error ("array types not implemented");
+ struct type *range_type;
+
+ while (dims-- > 0)
+ {
+ range_type = create_range_type (NULL, builtin_type_int, 0, 0);
+
+ type = create_array_type (NULL, type, range_type);
+ }
+
+ return type;
}
/* Create a Java string in the inferior from a (Utf8) literal. */
error ("not implemented - java_value_string"); /* FIXME */
}
+static void java_printchar PARAMS ((int c, GDB_FILE *stream));
+
+static void
+java_printchar (c, stream)
+ int c;
+ GDB_FILE *stream;
+{
+ fputc_filtered ('\'', stream);
+
+ switch (c)
+ {
+ case '\\':
+ case '\'':
+ fprintf_filtered (stream, "\\%c", c);
+ break;
+ case '\b':
+ fputs_filtered ("\\b", stream);
+ break;
+ case '\t':
+ fputs_filtered ("\\t", stream);
+ break;
+ case '\n':
+ fputs_filtered ("\\n", stream);
+ break;
+ case '\f':
+ fputs_filtered ("\\f", stream);
+ break;
+ case '\r':
+ fputs_filtered ("\\r", stream);
+ break;
+ default:
+ if (isprint (c))
+ fputc_filtered (c, stream);
+ else
+ fprintf_filtered (stream, "\\u%.4x", (unsigned int) c);
+ break;
+ }
+
+ fputc_filtered ('\'', stream);
+}
+
static value_ptr
evaluate_subexp_java (expect_type, exp, pos, noside)
struct type *expect_type;
{
int pc = *pos;
int i;
+ char *name;
enum exp_opcode op = exp->elts[*pos].opcode;
- value_ptr arg1;
+ value_ptr arg1, arg2;
+ struct type *type;
switch (op)
{
case UNOP_IND:
if (noside == EVAL_SKIP)
goto nosideret;
return value_ind (arg1);
+
+ case BINOP_SUBSCRIPT:
+ (*pos)++;
+ arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+ arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ /* If the user attempts to subscript something that is not an
+ array or pointer type (like a plain int variable for example),
+ then report this as an error. */
+
+ COERCE_REF (arg1);
+ type = check_typedef (VALUE_TYPE (arg1));
+ name = TYPE_NAME (type);
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ type = check_typedef (TYPE_TARGET_TYPE (type));
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ && TYPE_TAG_NAME (type) != NULL
+ && TYPE_TAG_NAME (type)[0] == '[')
+ {
+ CORE_ADDR address;
+ long length, index;
+ struct type *el_type;
+ char buf4[4];
+
+ value_ptr clas = java_class_from_object(arg1);
+ value_ptr temp = clas;
+ /* Get CLASS_ELEMENT_TYPE of the array type. */
+ temp = value_struct_elt (&temp, NULL, "methods",
+ NULL, "structure");
+ VALUE_TYPE (temp) = VALUE_TYPE (clas);
+ el_type = type_from_class (temp);
+ if (TYPE_CODE (el_type) == TYPE_CODE_STRUCT)
+ el_type = lookup_pointer_type (el_type);
+
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (el_type, VALUE_LVAL (arg1));
+ address = value_as_pointer (arg1);
+ address += JAVA_OBJECT_SIZE;
+ read_memory (address, buf4, 4);
+ length = (long) extract_signed_integer (buf4, 4);
+ index = (long) value_as_long (arg2);
+ if (index >= length || index < 0)
+ error ("array index (%ld) out of bounds (length: %ld)",
+ index, length);
+ address = (address + 4) + index * TYPE_LENGTH (el_type);
+ return value_at (el_type, address, NULL);
+ }
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1));
+ else
+ return value_subscript (arg1, arg2);
+ }
+ if (name == NULL)
+ name == TYPE_TAG_NAME (type);
+ if (name)
+ error ("cannot subscript something of type `%s'", name);
+ else
+ error ("cannot subscript requested type");
+
case OP_STRING:
(*pos)++;
i = longest_to_int (exp->elts[pc + 1].longconst);
if (noside == EVAL_SKIP)
goto nosideret;
return java_value_string (&exp->elts[pc + 2].string, i);
+
+ case STRUCTOP_STRUCT:
+ arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside);
+ /* Convert object field (such as TYPE.class) to reference. */
+ if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT)
+ arg1 = value_addr (arg1);
+ return arg1;
default:
break;
}
java_parse,
java_error,
evaluate_subexp_java,
- c_printchar, /* Print a character constant */
+ java_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
java_create_fundamental_type, /* Create fundamental type in this language */
java_print_type, /* Print a type using appropriate syntax */
{"%ld", "", "d", ""}, /* Decimal format info */
{"0x%lx", "0x", "x", ""}, /* Hex format info */
java_op_print_tab, /* expression operators for printing */
- 1, /* c-style arrays */
+ 0, /* not c-style arrays */
0, /* String lower bound */
&builtin_type_char, /* Type of string elements */
LANG_MAGIC
};
void
-_initialize_jave_language ()
+_initialize_java_language ()
{
java_int_type = init_type (TYPE_CODE_INT, 4, 0, "int", NULL);
add_language (&java_language_defn);
}
-/* Cleanup code that should be urn on every "run".
- We need some hook to have this actually be called ... FIXME */
+/* Cleanup code that should be run on every "run".
+ We should use make_run_cleanup to have this be called.
+ But will that mess up values in value histry? FIXME */
void java_rerun_cleanup ()
{