From 9981c44b92386c6d642ef71245fab27974f08dbf Mon Sep 17 00:00:00 2001 From: tromey Date: Thu, 15 Sep 2005 22:02:13 +0000 Subject: [PATCH] PR libgcj/16032: * interpret.cc (AVAL1U): Resolve pool entry when not direct threaded. (AVAL2U): Likewise. (compile): Handle 'ldc class' specially. (_Jv_InterpMethod::run): Added special 'ldc class' instruction. * verify.cc (check_constant): Handle 'ldc class' for 1.5 classes. * defineclass.cc (handleCodeAttribute): Set new field. (MAJOR_1_1, MINOR_1_1, MAJOR_1_2, MINOR_1_2, MAJOR_1_3, MINOR_1_3, MAJOR_1_4, MINOR_1_4, MAJOR_1_5, MINOR_1_5): New defines. (parse): Check version numbers. (_Jv_ClassReader::is_15): New field. (_Jv_ClassReader): Initialize it. * include/java-interp.h (_Jv_InterpMethod::is_15): New field. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@104325 138bc75d-0d04-0410-961f-82ee72b054a4 --- libjava/ChangeLog | 17 +++++++++++++++ libjava/defineclass.cc | 34 +++++++++++++++++++++++------ libjava/include/java-interp.h | 4 +++- libjava/interpret.cc | 51 +++++++++++++++++++++++++++++++++++++++---- libjava/verify.cc | 11 ++++++---- 5 files changed, 101 insertions(+), 16 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index ad81598..3520d8c 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,5 +1,22 @@ 2005-09-15 Tom Tromey + PR libgcj/16032: + * interpret.cc (AVAL1U): Resolve pool entry when not direct + threaded. + (AVAL2U): Likewise. + (compile): Handle 'ldc class' specially. + (_Jv_InterpMethod::run): Added special 'ldc class' instruction. + * verify.cc (check_constant): Handle 'ldc class' for 1.5 classes. + * defineclass.cc (handleCodeAttribute): Set new field. + (MAJOR_1_1, MINOR_1_1, MAJOR_1_2, MINOR_1_2, MAJOR_1_3, MINOR_1_3, + MAJOR_1_4, MINOR_1_4, MAJOR_1_5, MINOR_1_5): New defines. + (parse): Check version numbers. + (_Jv_ClassReader::is_15): New field. + (_Jv_ClassReader): Initialize it. + * include/java-interp.h (_Jv_InterpMethod::is_15): New field. + +2005-09-15 Tom Tromey + For PR libgcj/23288: * java/net/URLClassLoader.java (definePackage): Correctly order arguments to definePackage. Look up per-entry Attributes. diff --git a/libjava/defineclass.cc b/libjava/defineclass.cc index d12e327..89e0636 100644 --- a/libjava/defineclass.cc +++ b/libjava/defineclass.cc @@ -101,13 +101,17 @@ struct _Jv_ClassReader // the class to define (see java-interp.h) jclass def; - + // the classes associated interpreter data. _Jv_InterpClass *def_interp; // The name we found. _Jv_Utf8Const **found_name; + // True if this is a 1.5 class file. + bool is_15; + + /* check that the given number of input bytes are available */ inline void check (int num) { @@ -233,6 +237,8 @@ struct _Jv_ClassReader bytes = (unsigned char*) (elements (data)+offset); len = length; pos = 0; + is_15 = false; + def = klass; found_name = name_result; @@ -302,19 +308,32 @@ _Jv_DefineClass (jclass klass, jbyteArray data, jint offset, jint length, /** This section defines the parsing/scanning of the class data */ +// Major and minor version numbers for various releases. +#define MAJOR_1_1 45 +#define MINOR_1_1 3 +#define MAJOR_1_2 46 +#define MINOR_1_2 0 +#define MAJOR_1_3 47 +#define MINOR_1_3 0 +#define MAJOR_1_4 48 +#define MINOR_1_4 0 +#define MAJOR_1_5 49 +#define MINOR_1_5 0 + void _Jv_ClassReader::parse () { int magic = read4 (); - - /* FIXME: Decide which range of version numbers to allow */ - - /* int minor_version = */ read2u (); - /* int major_verson = */ read2u (); - if (magic != (int) 0xCAFEBABE) throw_class_format_error ("bad magic number"); + int minor_version = read2u (); + int major_version = read2u (); + if (major_version < MAJOR_1_1 || major_version > MAJOR_1_5 + || (major_version == MAJOR_1_5 && minor_version > MINOR_1_5)) + throw_class_format_error ("unrecognized class file version"); + is_15 = (major_version == MAJOR_1_5); + pool_count = read2u (); read_constpool (); @@ -1318,6 +1337,7 @@ void _Jv_ClassReader::handleCodeAttribute method->max_locals = max_locals; method->code_length = code_length; method->exc_count = exc_table_length; + method->is_15 = is_15; method->defining_class = def; method->self = &def->methods[method_index]; method->prepared = NULL; diff --git a/libjava/include/java-interp.h b/libjava/include/java-interp.h index 5155557c..269e39c 100644 --- a/libjava/include/java-interp.h +++ b/libjava/include/java-interp.h @@ -137,6 +137,7 @@ class _Jv_InterpMethod : public _Jv_MethodBase int code_length; _Jv_ushort exc_count; + bool is_15; // Length of the line_table - when this is zero then line_table is NULL. int line_table_len; @@ -218,7 +219,8 @@ _Jv_GetFirstMethod (_Jv_InterpClass *klass) return klass->interpreted_methods; } -struct _Jv_ResolvedMethod { +struct _Jv_ResolvedMethod +{ jint stack_item_count; jint vtable_index; jclass klass; diff --git a/libjava/interpret.cc b/libjava/interpret.cc index dcda95e..dacf19d 100644 --- a/libjava/interpret.cc +++ b/libjava/interpret.cc @@ -507,7 +507,16 @@ _Jv_InterpMethod::compile (const void * const *insn_targets) { int index = get1u (pc); ++pc; - SET_DATUM (pool_data[index].o); + // For an unresolved class we want to delay resolution + // until execution. + if (defining_class->constants.tags[index] == JV_CONSTANT_Class) + { + --next; + SET_INSN (insn_targets[int (op_jsr_w) + 1]); + SET_INT (index); + } + else + SET_DATUM (pool_data[index].o); } break; @@ -537,7 +546,16 @@ _Jv_InterpMethod::compile (const void * const *insn_targets) { int index = get2u (pc); pc += 2; - SET_DATUM (pool_data[index].o); + // For an unresolved class we want to delay resolution + // until execution. + if (defining_class->constants.tags[index] == JV_CONSTANT_Class) + { + --next; + SET_INSN (insn_targets[int (op_jsr_w) + 1]); + SET_INT (index); + } + else + SET_DATUM (pool_data[index].o); } break; @@ -1017,7 +1035,11 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth) INSN_LABEL(ifnonnull), INSN_LABEL(goto_w), INSN_LABEL(jsr_w), +#ifdef DIRECT_THREADED + INSN_LABEL (ldc_class) +#else 0 +#endif }; pc_t pc; @@ -1058,8 +1080,16 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth) #define GET2S() (pc += 2, get2s (pc- 2)) #define GET1U() get1u (pc++) #define GET2U() (pc += 2, get2u (pc - 2)) -#define AVAL1U() ({ int index = get1u (pc++); pool_data[index].o; }) -#define AVAL2U() ({ int index = get2u (pc); pc += 2; pool_data[index].o; }) + // Note that these could be more efficient when not handling 'ldc + // class'. +#define AVAL1U() \ + ({ int index = get1u (pc++); \ + resolve_pool_entry (meth->defining_class, index).o; }) +#define AVAL2U() \ + ({ int index = get2u (pc); pc += 2; \ + resolve_pool_entry (meth->defining_class, index).o; }) + // Note that we don't need to resolve the pool entry here as class + // constants are never wide. #define AVAL2UP() ({ int index = get2u (pc); pc += 2; &pool_data[index]; }) #define SKIP_GOTO pc += 2 #define GOTO_VAL() pc - 1 + get2s (pc) @@ -1320,6 +1350,19 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth) PUSHA ((jobject) AVAL2U ()); NEXT_INSN; +#ifdef DIRECT_THREADED + // For direct threaded we have a separate 'ldc class' operation. + insn_ldc_class: + { + // We could rewrite the instruction at this point. + int index = INTVAL (); + jobject k = (_Jv_Linker::resolve_pool_entry (meth->defining_class, + index)).o; + PUSHA (k); + } + NEXT_INSN; +#endif /* DIRECT_THREADED */ + insn_ldc2_w: { void *where = AVAL2UP (); diff --git a/libjava/verify.cc b/libjava/verify.cc index 3869bff..8b9cfcc 100644 --- a/libjava/verify.cc +++ b/libjava/verify.cc @@ -1950,13 +1950,16 @@ private: { check_pool_index (index); _Jv_Constants *pool = ¤t_class->constants; - if (pool->tags[index] == JV_CONSTANT_ResolvedString - || pool->tags[index] == JV_CONSTANT_String) + int tag = pool->tags[index]; + if (tag == JV_CONSTANT_ResolvedString || tag == JV_CONSTANT_String) return type (&java::lang::String::class$, this); - else if (pool->tags[index] == JV_CONSTANT_Integer) + else if (tag == JV_CONSTANT_Integer) return type (int_type); - else if (pool->tags[index] == JV_CONSTANT_Float) + else if (tag == JV_CONSTANT_Float) return type (float_type); + else if (current_method->is_15 + && (tag == JV_CONSTANT_ResolvedClass || tag == JV_CONSTANT_Class)) + return type (&java::lang::Class::class$, this); verify_fail ("String, int, or float constant expected", start_PC); } -- 2.7.4