* src/vm/class.c (vm/suck.h): Added.
authortwisti <none@none>
Mon, 18 Dec 2006 18:21:37 +0000 (18:21 +0000)
committertwisti <none@none>
Mon, 18 Dec 2006 18:21:37 +0000 (18:21 +0000)
(class_load_attribute_sourcefile): New function.
(class_load_attribute_enclosingmethod): Likewise.
(class_load_attributes): Likewise.

* src/vm/loader.c [ENABLE_JAVASE] (vm/annotation.h, vm/stackmap.h):
Added.
(skipattributebody): Renamed to loader_skip_attribute_body, made
non-static.
(skipattributes): Removed.
(loader_load_attribute_signature): New function.
(load_field): Use loader_load_attribute_signature.
(load_method): Renamed to loader_load_method, call
stackmap_load_attribute_stackmaptable and
loader_load_attribute_signature.
(load_attributes): Removed.
(load_class_from_classbuffer): Renamed load_method to
loader_load_method and load_attributes to class_load_attributes.
* src/vm/loader.h (loader_skip_attribute_body): Added.
[ENABLE_JAVASE] (loader_load_attribute_signature): Likewise.

* src/vm/method.h [ENABLE_JAVASE] (vm/stackmap.h): Added.
(methodinfo) [ENABLE_JAVASE]: Added signature and stack_map.

* src/vm/statistics.c (size_stack_map): Added.
(print_stats): Print stack_map size.
* src/vm/statistics.h (size_stack_map): Likewise.

* src/vm/global.h (JAVA_VERSION): Changed to "1.5.0".
(CLASS_VERSION): Changed to "50.0".
(MAJOR_VERSION): Changed to 50.

* src/vm/utf8.c [ENABLE_JAVASE] (utf_EnclosingMethod)
(utf_RuntimeVisibleAnnotations, utf_StackMapTable): Added.
(utf8_init) [ENABLE_JAVASE]: Init utf_EnclosingMethod,
utf_RuntimeVisibleAnnotations and utf_StackMapTable.
* src/vm/utf8.h [ENABLE_JAVASE] (utf_EnclosingMethod)
(utf_RuntimeVisibleAnnotations, utf_StackMapTable): Added.

* src/vm/properties.c (properties_init): Changed
java.specification.version to 1.5.

* src/vm/Makefile.am [ENABLE_JAVASE] (ANNOTATION_OBJ): Renamed to
ANNOTATION_SOURCES.
[ENABLE_JAVASE] (STACKMAP_SOURCES): Added.
[ENABLE_STATISTICS] (STATISTICS_OBJ): Renamed to STATISTICS_SOURCES.
(libvmcore_la_SOURCES): Added STACKMAP_SOURCES.
* src/vm/stackmap.c: New file.
* src/vm/stackmap.h: Likewise.

13 files changed:
src/vm/Makefile.am
src/vm/class.c
src/vm/global.h
src/vm/loader.c
src/vm/loader.h
src/vm/method.h
src/vm/properties.c
src/vm/stackmap.c [new file with mode: 0644]
src/vm/stackmap.h [new file with mode: 0644]
src/vm/statistics.c
src/vm/statistics.h
src/vm/utf8.c
src/vm/utf8.h

index 09cbf4e35d545108a8956cc12efe93052ed642bb..9c6da3a59246899f6df1cfbc2ec0770feb30ba49 100644 (file)
@@ -26,7 +26,7 @@
 ##
 ## Authors: Christian Thalinger
 ##
-## $Id: Makefile.am 6084 2006-11-29 17:04:14Z twisti $
+## $Id: Makefile.am 6216 2006-12-18 18:21:37Z twisti $
 
 ## Process this file with automake to produce Makefile.in
 
@@ -37,13 +37,17 @@ LIBS =
 SUBDIRS = jit
 
 if ENABLE_JAVASE
-ANNOTATION_OBJ = \
+ANNOTATION_SOURCES = \
        annotation.c \
        annotation.h
+
+STACKMAP_SOURCES = \
+       stackmap.c \
+       stackmap.h
 endif
 
 if ENABLE_STATISTICS
-STATISTICS_OBJ = \
+STATISTICS_SOURCES = \
        statistics.c \
        statistics.h
 endif
@@ -76,7 +80,7 @@ noinst_LTLIBRARIES = \
 libvmcore_la_SOURCES = \
        access.c \
        access.h \
-       $(ANNOTATION_OBJ) \
+       $(ANNOTATION_SOURCES) \
        builtin.c \
        builtin.h \
        builtintable.inc \
@@ -110,9 +114,10 @@ libvmcore_la_SOURCES = \
        resolve.h \
        $(RT_TIMING_OBJ) \
        rt-timing.h \
-       $(STATISTICS_OBJ) \
+       $(STATISTICS_SOURCES) \
        signal.c \
        signallocal.h \
+       $(STACKMAP_SOURCES) \
        string.c \
        stringlocal.h \
        suck.c \
index 50b6fd24fa48fa450de1c7f49fc705b732a53e83..62c541fd80faadc29206af5675784922423e3a56 100644 (file)
    Contact: cacao@cacaojvm.org
 
    Authors: Reinhard Grafl
-
-   Changes: Mark Probst
+            Mark Probst
             Andreas Krall
             Christian Thalinger
-                       Edwin Steiner
+            Edwin Steiner
 
-   $Id: class.c 6033 2006-11-21 16:56:56Z michi $
+   $Id: class.c 6216 2006-12-18 18:21:37Z twisti $
 
 */
 
@@ -60,6 +59,7 @@
 #include "vm/resolve.h"
 #include "vm/statistics.h"
 #include "vm/stringlocal.h"
+#include "vm/suck.h"
 #include "vm/utf8.h"
 
 
@@ -263,6 +263,254 @@ void class_postset_header_vftbl(void)
 }
 
 
+/* class_load_attribute_sourcefile *********************************************
+
+   SourceFile_attribute {
+       u2 attribute_name_index;
+       u4 attribute_length;
+          u2 sourcefile_index;
+   }
+
+*******************************************************************************/
+
+static bool class_load_attribute_sourcefile(classbuffer *cb)
+{
+       classinfo *c;
+       u4         attribute_length;
+       u2         sourcefile_index;
+       utf       *sourcefile;
+
+       /* get classinfo */
+
+       c = cb->class;
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 4 + 2))
+               return false;
+
+       /* check attribute length */
+
+       attribute_length = suck_u4(cb);
+
+       if (attribute_length != 2) {
+               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
+               return false;
+       }
+
+       /* there can be no more than one SourceFile attribute */
+
+       if (c->sourcefile != NULL) {
+               exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
+               return false;
+       }
+
+       /* get sourcefile */
+
+       sourcefile_index = suck_u2(cb);
+       sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
+
+       if (sourcefile == NULL)
+               return false;
+
+       /* store sourcefile */
+
+       c->sourcefile = sourcefile;
+
+       return true;
+}
+
+
+/* class_load_attribute_enclosingmethod ****************************************
+
+   EnclosingMethod_attribute {
+       u2 attribute_name_index;
+       u4 attribute_length;
+          u2 class_index;
+          u2 method_index;
+   }
+
+*******************************************************************************/
+
+static bool class_load_attribute_enclosingmethod(classbuffer *cb)
+{
+       classinfo             *c;
+       u4                     attribute_length;
+       u2                     class_index;
+       u2                     method_index;
+       classref_or_classinfo  cr;
+       constant_nameandtype  *cn;
+
+       /* get classinfo */
+
+       c = cb->class;
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
+               return false;
+
+       /* check attribute length */
+
+       attribute_length = suck_u4(cb);
+
+       if (attribute_length != 4) {
+               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
+               return false;
+       }
+
+       /* there can be no more than one EnclosingMethod attribute */
+
+       if (c->enclosingmethod != NULL) {
+               exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
+               return false;
+       }
+
+       /* get class index */
+
+       class_index = suck_u2(cb);
+       cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
+
+       /* get method index */
+
+       method_index = suck_u2(cb);
+       cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
+
+       /* store info in classinfo */
+
+       c->enclosingclass.any = cr.any;
+       c->enclosingmethod    = cn;
+
+       return true;
+}
+
+
+/* class_load_attributes *******************************************************
+
+   Read attributes from ClassFile.
+
+   attribute_info {
+       u2 attribute_name_index;
+       u4 attribute_length;
+       u1 info[attribute_length];
+   }
+
+   InnerClasses_attribute {
+       u2 attribute_name_index;
+       u4 attribute_length;
+   }
+
+*******************************************************************************/
+
+bool class_load_attributes(classbuffer *cb)
+{
+       classinfo *c;
+       u4         i, j;
+       u2         attributes_count;
+       u2         attribute_name_index;
+       utf       *attribute_name;
+
+       c = cb->class;
+
+       /* get attributes count */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       attributes_count = suck_u2(cb);
+
+       for (i = 0; i < attributes_count; i++) {
+               /* get attribute name */
+
+               if (!suck_check_classbuffer_size(cb, 2))
+                       return false;
+
+               attribute_name_index = suck_u2(cb);
+               attribute_name =
+                       class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
+
+               if (attribute_name == NULL)
+                       return false;
+
+               if (attribute_name == utf_InnerClasses) {
+                       /* InnerClasses */
+
+                       if (c->innerclass != NULL) {
+                               exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
+                               return false;
+                       }
+                               
+                       if (!suck_check_classbuffer_size(cb, 4 + 2))
+                               return false;
+
+                       /* skip attribute length */
+                       suck_u4(cb);
+
+                       /* number of records */
+                       c->innerclasscount = suck_u2(cb);
+
+                       if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
+                               return false;
+
+                       /* allocate memory for innerclass structure */
+                       c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
+
+                       for (j = 0; j < c->innerclasscount; j++) {
+                               /* The innerclass structure contains a class with an encoded
+                                  name, its defining scope, its simple name and a bitmask of
+                                  the access flags. If an inner class is not a member, its
+                                  outer_class is NULL, if a class is anonymous, its name is
+                                  NULL. */
+                                                               
+                               innerclassinfo *info = c->innerclass + j;
+
+                               info->inner_class.ref =
+                                       innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
+                               info->outer_class.ref =
+                                       innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
+                               info->name =
+                                       innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
+                               info->flags = suck_u2(cb);
+                       }
+               }
+               else if (attribute_name == utf_SourceFile) {
+                       /* SourceFile */
+
+                       if (!class_load_attribute_sourcefile(cb))
+                               return false;
+               }
+#if defined(ENABLE_JAVASE)
+               else if (attribute_name == utf_EnclosingMethod) {
+                       /* EnclosingMethod */
+
+                       if (!class_load_attribute_enclosingmethod(cb))
+                               return false;
+               }
+               else if (attribute_name == utf_Signature) {
+                       /* Signature */
+
+                       if (!loader_load_attribute_signature(cb, &(c->signature)))
+                               return false;
+               }
+               else if (attribute_name == utf_RuntimeVisibleAnnotations) {
+                       /* RuntimeVisibleAnnotations */
+
+                       if (!annotation_load_attribute_runtimevisibleannotations(cb))
+                               return false;
+               }
+#endif
+               else {
+                       /* unknown attribute */
+
+                       if (!loader_skip_attribute_body(cb))
+                               return false;
+               }
+       }
+
+       return true;
+}
+
+
 /* class_freepool **************************************************************
 
        Frees all resources used by this classes Constant Pool.
@@ -328,8 +576,8 @@ voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
        /* check index and type of constantpool entry */
        /* (pos == 0 is caught by type comparison) */
 
-       if (pos >= c->cpcount || c->cptags[pos] != ctype) {
-               *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
+       if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
+               exceptions_throw_classformaterror(c, "Illegal constant pool index");
                return NULL;
        }
 
@@ -346,16 +594,19 @@ voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
 {
        /* invalid position in constantpool */
+
        if (pos >= c->cpcount) {
-               *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
+               exceptions_throw_classformaterror(c, "Illegal constant pool index");
                return NULL;
        }
 
        /* constantpool entry of type 0 */      
-       if (!c->cptags[pos])
+
+       if (c->cptags[pos] == 0)
                return NULL;
 
        /* check type of constantpool entry */
+
        if (c->cptags[pos] != ctype) {
                *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
                return NULL;
index 1ab05e4670a5d1e108ef93295bc0ddeffc999a59..5943147facc44310f03490214740fd565606802f 100644 (file)
 
    Authors: Reinhard Grafl
             Andreas Krall
-
-   Changes: Mark Probst
+            Mark Probst
             Philipp Tomsich
             Edwin Steiner
             Joseph Wenninger
             Christian Thalinger
 
-   $Id: global.h 6030 2006-11-20 14:18:12Z michi $
+   $Id: global.h 6216 2006-12-18 18:21:37Z twisti $
 
 */
 
@@ -146,14 +145,14 @@ typedef struct java_objectarray java_objectarray;
 
 /* some Java related defines **************************************************/
 
-#define JAVA_VERSION    "1.4.2"         /* this version is supported by CACAO */
-#define CLASS_VERSION   "49.0"
+#define JAVA_VERSION    "1.5.0"         /* this version is supported by CACAO */
+#define CLASS_VERSION   "50.0"
 
 
 /* Java class file constants **************************************************/
 
 #define MAGIC             0xCAFEBABE
-#define MAJOR_VERSION     49
+#define MAJOR_VERSION     50
 #define MINOR_VERSION     0
 
 
index 9386ac59d399d4dad05c9c833db3d03d5f7b2203..5433718a1eb633f6270fa7ec7a106dbd7bea02fd 100644 (file)
@@ -31,7 +31,7 @@
             Edwin Steiner
             Christian Thalinger
 
-   $Id: loader.c 6033 2006-11-21 16:56:56Z michi $
+   $Id: loader.c 6216 2006-12-18 18:21:37Z twisti $
 
 */
 
 #endif
 
 #include "toolbox/logging.h"
+
+#if defined(ENABLE_JAVASE)
+# include "vm/annotation.h"
+# include "vm/stackmap.h"
+#endif
+
 #include "vm/builtin.h"
 #include "vm/classcache.h"
 #include "vm/exceptions.h"
@@ -277,54 +283,31 @@ void loader_load_all_classes(void)
 }
 
 
-/* skipattributebody ***********************************************************
+/* loader_skip_attribute_body **************************************************
 
-   Skips an attribute after the 16 bit reference to attribute_name has
-   already been read.
+   Skips an attribute the attribute_name_index has already been read.
        
+   attribute_info {
+       u2 attribute_name_index;
+       u4 attribute_length;
+       u1 info[attribute_length];
+   }
+
 *******************************************************************************/
 
-static bool skipattributebody(classbuffer *cb)
+bool loader_skip_attribute_body(classbuffer *cb)
 {
-       u4 len;
+       u4 attribute_length;
 
        if (!suck_check_classbuffer_size(cb, 4))
                return false;
 
-       len = suck_u4(cb);
+       attribute_length = suck_u4(cb);
 
-       if (!suck_check_classbuffer_size(cb, len))
+       if (!suck_check_classbuffer_size(cb, attribute_length))
                return false;
 
-       suck_skip_nbytes(cb, len);
-
-       return true;
-}
-
-
-/************************* Function: skipattributes ****************************
-
-       skips num attribute structures
-       
-*******************************************************************************/
-
-static bool skipattributes(classbuffer *cb, u4 num)
-{
-       u4 i;
-       u4 len;
-
-       for (i = 0; i < num; i++) {
-               if (!suck_check_classbuffer_size(cb, 2 + 4))
-                       return false;
-
-               suck_u2(cb);
-               len = suck_u4(cb);
-
-               if (!suck_check_classbuffer_size(cb, len))
-                       return false;
-
-               suck_skip_nbytes(cb, len);
-       }
+       suck_skip_nbytes(cb, attribute_length);
 
        return true;
 }
@@ -779,6 +762,58 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
 }
 
 
+/* loader_load_attribute_signature *********************************************
+
+   Signature_attribute {
+       u2 attribute_name_index;
+          u4 atrribute_length;
+          u2 signature_index;
+   }
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
+{
+       classinfo *c;
+       u4         attribute_length;
+       u2         signature_index;
+
+       /* get classinfo */
+
+       c = cb->class;
+
+       /* check remaining bytecode */
+
+       if (!suck_check_classbuffer_size(cb, 4 + 2))
+               return false;
+
+       /* check attribute length */
+
+       attribute_length = suck_u4(cb);
+
+       if (attribute_length != 2) {
+               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
+               return false;
+       }
+
+       if (*signature != NULL) {
+               exceptions_throw_classformaterror(c, "Multiple Signature attributes");
+               return false;
+       }
+
+       /* get signature */
+
+       signature_index = suck_u2(cb);
+
+       if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
+               return false;
+
+       return true;
+}
+#endif /* defined(ENABLE_JAVASE) */
+
+
 /* load_field ******************************************************************
 
    Load everything about a class field from the class file and fill a
@@ -980,28 +1015,18 @@ static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
                                log_text("Invalid Constant - Type");
                        }
                }
+#if defined(ENABLE_JAVASE)
                else if (u == utf_Signature) {
-                       if (!suck_check_classbuffer_size(cb, 4 + 2))
-                               return false;
-
-                       /* check attribute length */
+                       /* Signature */
 
-                       if (suck_u4(cb) != 2) {
-                               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
-                               return false;
-                       }
-
-                       if (f->signature != NULL) {
-                               exceptions_throw_classformaterror(c, "Multiple Signature attributes");
-                               return false;
-                       }
-
-                       if (!(f->signature = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
+                       if (!loader_load_attribute_signature(cb, &(f->signature)))
                                return false;
                }
+#endif
                else {
                        /* unknown attribute */
-                       if (!skipattributebody(cb))
+
+                       if (!loader_skip_attribute_body(cb))
                                return false;
                }
        }
@@ -1012,23 +1037,56 @@ static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
 }
 
 
-/* load_method *****************************************************************
+/* loader_load_method **********************************************************
 
    Loads a method from the class file and fills an existing
    'methodinfo' structure. For native methods, the function pointer
    field is set to the real function pointer, for JavaVM methods a
    pointer to the compiler is used preliminarily.
-       
+
+   method_info {
+       u2 access_flags;
+          u2 name_index;
+          u2 descriptor_index;
+          u2 attributes_count;
+          attribute_info attributes[attribute_count];
+   }
+
+   attribute_info {
+       u2 attribute_name_index;
+          u4 attribute_length;
+          u1 info[attribute_length];
+   }
+
+   LineNumberTable_attribute {
+       u2 attribute_name_index;
+          u4 attribute_length;
+          u2 line_number_table_length;
+          {
+              u2 start_pc;
+                  u2 line_number;
+          } line_number_table[line_number_table_length];
+   }
+
 *******************************************************************************/
 
-static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
+static bool loader_load_method(classbuffer *cb, methodinfo *m,
+                                                          descriptor_pool *descpool)
 {
        classinfo *c;
        int argcount;
-       s4 i, j;
-       u4 attrnum;
-       u4 codeattrnum;
-       utf *u;
+       s4         i, j, k, l;
+       utf       *u;
+       u2         name_index;
+       u2         descriptor_index;
+       u2         attributes_count;
+       u2         attribute_name_index;
+       utf       *attribute_name;
+       u2         code_attributes_count;
+       u2         code_attribute_name_index;
+       utf       *code_attribute_name;
+
+       /* get classinfo */
 
        c = cb->class;
 
@@ -1043,19 +1101,29 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
 
        /* all fields of m have been zeroed in load_class_from_classbuffer */
 
-       m->class                 = c;
+       m->class = c;
        
        if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
                return false;
 
+       /* access flags */
+
        m->flags = suck_u2(cb);
 
-       if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
+       /* name */
+
+       name_index = suck_u2(cb);
+
+       if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
                return false;
 
        m->name = u;
 
-       if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
+       /* descriptor */
+
+       descriptor_index = suck_u2(cb);
+
+       if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
                return false;
 
        m->descriptor = u;
@@ -1140,18 +1208,24 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
                
        if (!suck_check_classbuffer_size(cb, 2))
                return false;
-       
-       attrnum = suck_u2(cb);
-       for (i = 0; i < attrnum; i++) {
-               utf *aname;
 
+       /* attributes count */
+
+       attributes_count = suck_u2(cb);
+
+       for (i = 0; i < attributes_count; i++) {
                if (!suck_check_classbuffer_size(cb, 2))
                        return false;
 
-               if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
+               /* attribute name index */
+
+               attribute_name_index = suck_u2(cb);
+
+               if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
                        return false;
 
-               if (aname == utf_Code) {
+               if (attribute_name == utf_Code) {
+                       /* Code */
                        if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
                                exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
                                return false;
@@ -1233,24 +1307,34 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
                        if (!suck_check_classbuffer_size(cb, 2))
                                return false;
 
-                       codeattrnum = suck_u2(cb);
+                       /* code attributes count */
 
-                       for (; codeattrnum > 0; codeattrnum--) {
-                               utf *caname;
+                       code_attributes_count = suck_u2(cb);
 
+                       for (k = 0; k < code_attributes_count; k++) {
                                if (!suck_check_classbuffer_size(cb, 2))
                                        return false;
 
-                               if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
+                               /* code attribute name index */
+
+                               code_attribute_name_index = suck_u2(cb);
+
+                               if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
                                        return false;
 
-                               if (caname == utf_LineNumberTable) {
-                                       u2 lncid;
+                               /* check which code attribute */
 
+                               if (code_attribute_name == utf_LineNumberTable) {
+                                       /* LineNumberTable */
                                        if (!suck_check_classbuffer_size(cb, 4 + 2))
                                                return false;
 
-                                       suck_u4(cb);
+                                       /* attribute length */
+
+                                       (void) suck_u4(cb);
+
+                                       /* line number table length */
+
                                        m->linenumbercount = suck_u2(cb);
 
                                        if (!suck_check_classbuffer_size(cb,
@@ -1259,27 +1343,29 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
 
                                        m->linenumbers = MNEW(lineinfo, m->linenumbercount);
                                        
-                                       for (lncid = 0; lncid < m->linenumbercount; lncid++) {
-                                               m->linenumbers[lncid].start_pc = suck_u2(cb);
-                                               m->linenumbers[lncid].line_number = suck_u2(cb);
+                                       for (l = 0; l < m->linenumbercount; l++) {
+                                               m->linenumbers[l].start_pc    = suck_u2(cb);
+                                               m->linenumbers[l].line_number = suck_u2(cb);
                                        }
-                                       codeattrnum--;
+                               }
+                               else if (code_attribute_name == utf_StackMapTable) {
+                                       /* StackTableMap */
 
-                                       if (!skipattributes(cb, codeattrnum))
+                                       if (!stackmap_load_attribute_stackmaptable(cb, m))
                                                return false;
-                                       
-                                       break;
+                               }
+                               else {
+                                       /* unknown code attribute */
 
-                               } else {
-                                       if (!skipattributebody(cb))
+                                       if (!loader_skip_attribute_body(cb))
                                                return false;
                                }
                        }
                }
-               else if (aname == utf_Exceptions) {
-                       s4 j;
+               else if (attribute_name == utf_Exceptions) {
+                       /* Exceptions */
 
-                       if (m->thrownexceptions) {
+                       if (m->thrownexceptions != NULL) {
                                exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
                                return false;
                        }
@@ -1287,7 +1373,10 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
                        if (!suck_check_classbuffer_size(cb, 4 + 2))
                                return false;
 
-                       suck_u4(cb); /* length */
+                       /* attribute length */
+
+                       (void) suck_u4(cb);
+
                        m->thrownexceptionscount = suck_u2(cb);
 
                        if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
@@ -1302,32 +1391,23 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
                                        return false;
                        }
                }
-               else if (aname == utf_Signature) {
-                       if (!suck_check_classbuffer_size(cb, 4 + 2))
-                               return false;
-
-                       /* check attribute length */
-
-                       if (suck_u4(cb) != 2) {
-                               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
-                               return false;
-                       }
+#if defined(ENABLE_JAVASE)
+               else if (attribute_name == utf_Signature) {
+                       /* Signature */
 
-                       if (m->signature != NULL) {
-                               exceptions_throw_classformaterror(c, "Multiple Signature attributes");
-                               return false;
-                       }
-
-                       if (!(m->signature = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
+                       if (!loader_load_attribute_signature(cb, &(m->signature)))
                                return false;
                }
+#endif
                else {
-                       if (!skipattributebody(cb))
+                       /* unknown attribute */
+
+                       if (!loader_skip_attribute_body(cb))
                                return false;
                }
        }
 
-       if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
+       if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
                exceptions_throw_classformaterror(c, "Missing Code attribute");
                return false;
        }
@@ -1338,120 +1418,6 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
 }
 
 
-/* load_attribute **************************************************************
-
-   Read attributes from classfile.
-       
-*******************************************************************************/
-
-static bool load_attributes(classbuffer *cb, u4 num)
-{
-       classinfo *c;
-       utf       *aname;
-       u4 i, j;
-
-       c = cb->class;
-
-       for (i = 0; i < num; i++) {
-               /* retrieve attribute name */
-
-               if (!suck_check_classbuffer_size(cb, 2))
-                       return false;
-
-               if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
-                       return false;
-
-               if (aname == utf_InnerClasses) {
-                       /* InnerClasses attribute */
-
-                       if (c->innerclass != NULL) {
-                               exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
-                               return false;
-                       }
-                               
-                       if (!suck_check_classbuffer_size(cb, 4 + 2))
-                               return false;
-
-                       /* skip attribute length */
-                       suck_u4(cb);
-
-                       /* number of records */
-                       c->innerclasscount = suck_u2(cb);
-
-                       if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
-                               return false;
-
-                       /* allocate memory for innerclass structure */
-                       c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
-
-                       for (j = 0; j < c->innerclasscount; j++) {
-                               /* The innerclass structure contains a class with an encoded
-                                  name, its defining scope, its simple name and a bitmask of
-                                  the access flags. If an inner class is not a member, its
-                                  outer_class is NULL, if a class is anonymous, its name is
-                                  NULL. */
-                                                               
-                               innerclassinfo *info = c->innerclass + j;
-
-                               info->inner_class.ref =
-                                       innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
-                               info->outer_class.ref =
-                                       innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
-                               info->name =
-                                       innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
-                               info->flags = suck_u2(cb);
-                       }
-               }
-               else if (aname == utf_SourceFile) {
-                       /* SourceFile attribute */
-
-                       if (!suck_check_classbuffer_size(cb, 4 + 2))
-                               return false;
-
-                       if (suck_u4(cb) != 2) {
-                               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
-                               return false;
-                       }
-
-                       if (c->sourcefile != NULL) {
-                               exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
-                               return false;
-                       }
-
-                       if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
-                               return false;
-               }
-               else if (aname == utf_Signature) {
-                       /* Signature attribute */
-
-                       if (!suck_check_classbuffer_size(cb, 4 + 2))
-                               return false;
-
-                       if (suck_u4(cb) != 2) {
-                               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
-                               return false;
-                       }
-
-                       if (c->signature != NULL) {
-                               exceptions_throw_classformaterror(c, "Multiple Signature attributes");
-                               return false;
-                       }
-
-                       if (!(c->signature = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
-                               return false;
-               }
-               else {
-                       /* unknown attribute */
-
-                       if (!skipattributebody(cb))
-                               return false;
-               }
-       }
-
-       return true;
-}
-
-
 /* load_class_from_sysloader ***************************************************
 
    Load the class with the given name using the system class loader
@@ -2104,7 +2070,7 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
        MZERO(c->methods, methodinfo, c->methodscount);
        
        for (i = 0; i < c->methodscount; i++) {
-               if (!load_method(cb, &(c->methods[i]),descpool))
+               if (!loader_load_method(cb, &(c->methods[i]), descpool))
                        goto return_exception;
        }
 
@@ -2349,10 +2315,7 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
 
        /* load attribute structures */
 
-       if (!suck_check_classbuffer_size(cb, 2))
-               goto return_exception;
-
-       if (!load_attributes(cb, suck_u2(cb)))
+       if (!class_load_attributes(cb))
                goto return_exception;
 
        /* Pre Java 1.5 version don't check this. This implementation is like
index 07034a8fa6bc92119eebdc78bbc7e8babf633964..ee2db94ca53617e7cfa3feae60bf700e6b361ff2 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Christian Thalinger
 
-   $Id: loader.h 4959 2006-05-26 12:09:29Z edwin $
+   $Id: loader.h 6216 2006-12-18 18:21:37Z twisti $
 */
 
 
@@ -122,6 +122,12 @@ bool loader_init(void);
 
 void loader_load_all_classes(void);
 
+bool loader_skip_attribute_body(classbuffer *cb);
+
+#if defined(ENABLE_JAVASE)
+bool loader_load_attribute_signature(classbuffer *cb, utf **signature);
+#endif
+
 /* free resources */
 void loader_close(void);
 
index ec57352af4ee9dbf5442075f55c255007a598b1e..59f50658944076e73f92b59902175e837ad6762c 100644 (file)
@@ -28,7 +28,7 @@
             Christian Thalinger
             Edwin Steiner
 
-   $Id: method.h 6012 2006-11-16 19:45:15Z twisti $
+   $Id: method.h 6216 2006-12-18 18:21:37Z twisti $
 */
 
 
@@ -50,6 +50,11 @@ typedef struct method_worklist     method_worklist;
 #include "vm/global.h"
 #include "vm/linker.h"
 #include "vm/references.h"
+
+#if defined(ENABLE_JAVASE)
+# include "vm/stackmap.h"
+#endif
+
 #include "vm/utf8.h"
 #include "vm/jit/code.h"
 #include "vm/jit/jit.h"
@@ -62,7 +67,11 @@ struct methodinfo {                 /* method structure                       */
        s4            flags;            /* ACC flags                              */
        utf          *name;             /* name of method                         */
        utf          *descriptor;       /* JavaVM descriptor string of method     */
-       utf          *signature;        /* Signature attribute string             */
+#if defined(ENABLE_JAVASE)
+       utf          *signature;        /* Signature attribute                    */
+       stack_map_t  *stack_map;        /* StackMapTable attribute                */
+#endif
+
        methoddesc   *parseddesc;       /* parsed descriptor                      */
                             
        classinfo    *class;            /* class, the method belongs to           */
index 37618e3f48901c4f69d44258b9528af9bd7e8722..08940ab163ed9284570873c0d040b87141664394 100644 (file)
@@ -26,7 +26,7 @@
 
    Authors: Christian Thalinger
 
-   $Id: properties.c 6015 2006-11-18 22:16:32Z twisti $
+   $Id: properties.c 6216 2006-12-18 18:21:37Z twisti $
 
 */
 
@@ -139,7 +139,7 @@ bool properties_init(void)
        properties_add("java.vm.version", VERSION);
        properties_add("java.vm.vendor", "CACAO Team");
        properties_add("java.vm.name", "CACAO");
-       properties_add("java.specification.version", "1.4");
+       properties_add("java.specification.version", "1.5");
        properties_add("java.specification.vendor", "Sun Microsystems Inc.");
        properties_add("java.specification.name", "Java Platform API Specification");
        properties_add("java.class.version", CLASS_VERSION);
diff --git a/src/vm/stackmap.c b/src/vm/stackmap.c
new file mode 100644 (file)
index 0000000..93c1b70
--- /dev/null
@@ -0,0 +1,530 @@
+/* src/vm/stackmap.c - class attribute StackMapTable
+
+   Copyright (C) 2006 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
+   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
+   Institut f. Computersprachen - TU Wien
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Contact: cacao@cacaojvm.org
+
+   Authors: Christian Thalinger
+
+   $Id: utf8.h 5920 2006-11-05 21:23:09Z twisti $
+
+*/
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "mm/memory.h"
+#include "vm/class.h"
+#include "vm/exceptions.h"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/stackmap.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
+#include "vm/suck.h"
+
+
+/* stackmap_get_verification_type_info *****************************************
+
+   union verification_type_info {
+       Top_variable_info;
+          Integer_variable_info;
+          Float_variable_info;
+          Long_variable_info;
+          Double_variable_info;
+          Null_variable_info;
+          UninitializedThis_variable_info;
+          Object_variable_info;
+          Uninitialized_variable_info;
+   }
+
+   Top_variable_info {
+       u1 tag = ITEM_Top;  // 0
+   }
+
+   Integer_variable_info {
+       u1 tag = ITEM_Integer;  // 1
+   }
+
+   Float_variable_info {
+       u1 tag = ITEM_Float;  // 2
+   }
+
+   Long_variable_info {
+       u1 tag = ITEM_Long;  // 4
+   }
+
+   Double_variable_info {
+       u1 tag = ITEM_Double;  // 3
+   }
+
+   Null_variable_info {
+       u1 tag = ITEM_Null;  // 5
+   }
+
+   UninitializedThis_variable_info {
+       u1 tag = ITEM_UninitializedThis;  // 6
+   }
+
+   Object_variable_info {
+       u1 tag = ITEM_Object;  // 7
+          u2 cpool_index;
+   }
+
+   Uninitialized_variable_info {
+       u1 tag = ITEM_Uninitialized;  // 8
+          u2 offset;
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_verification_type_info(classbuffer *cb, verification_type_info_t *verification_type_info)
+{
+       /* get verification type */
+
+       if (!suck_check_classbuffer_size(cb, 1))
+               return false;
+
+       verification_type_info->tag = suck_u1(cb);
+
+       /* process the tag */
+
+       switch (verification_type_info->tag) {
+       case ITEM_Top:
+       case ITEM_Integer:
+       case ITEM_Float:
+       case ITEM_Long:
+       case ITEM_Double:
+       case ITEM_Null:
+       case ITEM_UninitializedThis:
+               break;
+
+       case ITEM_Object:
+               /* get constant pool index */
+
+               if (!suck_check_classbuffer_size(cb, 2))
+                       return false;
+
+               verification_type_info->Object_variable_info.cpool_index = suck_u2(cb);
+               break;
+
+       case ITEM_Uninitialized:
+               /* get offset */
+
+               if (!suck_check_classbuffer_size(cb, 2))
+                       return false;
+
+               verification_type_info->Uninitialized_variable_info.offset = suck_u2(cb);
+               break;
+       }
+
+       return true;
+}
+
+
+/* stackmap_get_same_locals_1_stack_item_frame *********************************
+
+   same_locals_1_stack_item_frame {
+       u1 frame_type = SAME_LOCALS_1_STACK_ITEM;  // 64-127
+          verification_type_info stack[1];
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_same_locals_1_stack_item_frame(classbuffer *cb, stack_map_frame_t *stack_map_frame)
+{
+       same_locals_1_stack_item_frame_t *same_locals_1_stack_item_frame;
+
+       /* for convenience */
+
+       same_locals_1_stack_item_frame =
+               &(stack_map_frame->same_locals_1_stack_item_frame);
+
+       if (!stackmap_get_verification_type_info(cb, &(same_locals_1_stack_item_frame->stack[0])))
+               return false;
+
+       return true;
+}
+
+
+/* stackmap_get_same_locals_1_stack_item_frame_extended ************************
+
+   same_locals_1_stack_item_frame_extended {
+       u1 frame_type = SAME_LOCALS_1_STACK_ITEM_EXTENDED;  // 247
+          u2 offset_delta;
+          verification_type_info stack[1];
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_same_locals_1_stack_item_frame_extended(classbuffer *cb, stack_map_frame_t *stack_map_frame)
+{
+       same_locals_1_stack_item_frame_extended_t *same_locals_1_stack_item_frame_extended;
+
+       /* for convenience */
+
+       same_locals_1_stack_item_frame_extended =
+               &(stack_map_frame->same_locals_1_stack_item_frame_extended);
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       /* get offset delta */
+
+       same_locals_1_stack_item_frame_extended->offset_delta = suck_u2(cb);
+
+       /* process stack */
+
+       if (!stackmap_get_verification_type_info(cb, &(same_locals_1_stack_item_frame_extended->stack[0])))
+               return false;
+
+       return true;
+}
+
+
+/* stackmap_get_chop_frame *****************************************************
+
+   chop_frame {
+       u1 frame_type = CHOP_FRAME;  // 248-250
+          u2 offset_delta;
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_chop_frame(classbuffer *cb,
+                                                                       stack_map_frame_t *stack_map_frame)
+{
+       chop_frame_t *chop_frame;
+
+       /* for convenience */
+
+       chop_frame = &(stack_map_frame->chop_frame);
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       /* get offset delta */
+
+       chop_frame->offset_delta = suck_u2(cb);
+
+       return true;
+}
+
+
+/* stackmap_get_same_frame_extended ********************************************
+
+   same_frame_extended {
+       u1 frame_type = SAME_FRAME_EXTENDED;  // 251
+          u2 offset_delta;
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_same_frame_extended(classbuffer *cb,
+                                                                                        stack_map_frame_t *stack_map_frame)
+{
+       same_frame_extended_t *same_frame_extended;
+
+       /* for convenience */
+
+       same_frame_extended = &(stack_map_frame->same_frame_extended);
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       /* get offset delta */
+
+       same_frame_extended->offset_delta = suck_u2(cb);
+
+       return true;
+}
+
+
+/* stackmap_get_append_frame ***************************************************
+
+   append_frame {
+       u1 frame_type = APPEND_FRAME;  // 252-254
+          u2 offset_delta;
+          verification_type_info locals[frame_Type - 251];
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_append_frame(classbuffer *cb,
+                                                                         stack_map_frame_t *stack_map_frame)
+{
+       append_frame_t *append_frame;
+       s4              number_of_locals;
+       s4              i;
+
+       /* for convenience */
+
+       append_frame = &(stack_map_frame->append_frame);
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       /* get offset delta */
+
+       append_frame->offset_delta = suck_u2(cb);
+
+       /* allocate locals array */
+
+       number_of_locals = append_frame->frame_type - 251;
+
+       append_frame->locals = DMNEW(verification_type_info_t, number_of_locals);
+
+       /* process all locals */
+
+       for (i = 0; i < number_of_locals; i++)
+               if (!stackmap_get_verification_type_info(cb, &(append_frame->locals[i])))
+                       return false;
+
+       return true;
+}
+
+
+/* stackmap_get_full_frame *****************************************************
+
+   full_frame {
+       u1 frame_type = FULL_FRAME;
+          u2 offset_delta;
+          u2 number_of_locals;
+          verification_type_info locals[number_of_locals];
+          u2 number_of_stack_items;
+          verification_type_info stack[number_of_stack_items];
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_full_frame(classbuffer *cb,
+                                                                       stack_map_frame_t *stack_map_frame)
+{
+       full_frame_t *full_frame;
+       s4 i;
+
+       /* for convenience */
+
+       full_frame = &(stack_map_frame->full_frame);
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 2 + 2))
+               return false;
+
+       /*  get offset delta */
+
+       stack_map_frame->full_frame.offset_delta = suck_u2(cb);
+
+       /* get number of locals */
+
+       full_frame->number_of_locals = suck_u2(cb);
+
+       /* allocate locals array */
+
+       full_frame->locals =
+               DMNEW(verification_type_info_t, full_frame->number_of_locals);
+
+       /* process all locals */
+
+       for (i = 0; i < full_frame->number_of_locals; i++)
+               if (!stackmap_get_verification_type_info(cb, &(full_frame->locals[i])))
+                       return false;
+
+       /* get number of stack items */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       full_frame->number_of_stack_items = suck_u2(cb);
+
+       /* allocate stack array */
+
+       full_frame->stack =
+               DMNEW(verification_type_info_t, full_frame->number_of_stack_items);
+
+       /* process all stack items */
+
+       for (i = 0; i < full_frame->number_of_stack_items; i++)
+               if (!stackmap_get_verification_type_info(cb, &(full_frame->stack[i])))
+                       return false;
+
+       return true;
+}
+
+
+/* stackmap_load_attribute_stackmaptable ***************************************
+
+   stack_map {
+          u2 attribute_name_index;
+          u4 attribute_length;
+          u2 number_of_entries;
+          stack_map_frame entries[number_of_entries];
+   }
+
+   union stack_map_frame {
+       same_frame;
+          same_locals_1_stack_item_frame;
+          same_locals_1_stack_item_frame_extended;
+          chop_frame;
+          same_frame_extended;
+          append_frame;
+          full_frame;
+   }
+
+   same_frame {
+       u1 frame_type = SAME;  // 0-63
+   }
+
+*******************************************************************************/
+
+bool stackmap_load_attribute_stackmaptable(classbuffer *cb, methodinfo *m)
+{
+       classinfo       *c;
+       stack_map_t     *stack_map;
+       s4               i;
+       u1               frame_type;
+
+       /* get classinfo */
+
+       c = cb->class;
+
+       /* allocate stack map structure */
+
+       stack_map = DNEW(stack_map_t);
+
+       STATISTICS(size_stack_map += sizeof(stack_map_t));
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 4 + 2))
+               return false;
+
+       /* attribute_length */
+
+       stack_map->attribute_length = suck_u4(cb);
+
+       if (!suck_check_classbuffer_size(cb, stack_map->attribute_length))
+               return false;
+
+       /* get number of entries */
+
+       stack_map->number_of_entries = suck_u2(cb);
+
+       /* process all entries */
+
+       stack_map->entries = DMNEW(stack_map_frame_t, stack_map->number_of_entries);
+
+       for (i = 0; i < stack_map->number_of_entries; i++) {
+               /* get the frame type */
+
+               frame_type = suck_u1(cb);
+
+               stack_map->entries[i].frame_type = frame_type;
+
+               /* process frame */
+
+               if (frame_type <= FRAME_TYPE_SAME) {
+                       /* same_frame */
+               }
+               else if (frame_type <= FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM) {
+                       /* same_locals_1_stack_item_frame */
+
+                       if (!stackmap_get_same_locals_1_stack_item_frame(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+               else if (frame_type <= FRAME_TYPE_RESERVED) {
+                       /* reserved */
+
+                       exceptions_throw_classformaterror(c, "reserved frame type");
+                       return false;
+               }
+               else if (frame_type == FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
+                       /* same_locals_1_stack_item_frame_extended */
+
+                       if (!stackmap_get_same_locals_1_stack_item_frame_extended(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+               else if (frame_type <= FRAME_TYPE_CHOP) {
+                       /* chop_frame */
+
+                       if (!stackmap_get_chop_frame(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+               else if (frame_type == FRAME_TYPE_SAME_FRAME_EXTENDED) {
+                       /* same_frame_extended */
+
+                       if (!stackmap_get_same_frame_extended(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+               else if (frame_type <= FRAME_TYPE_APPEND) {
+                       /* append_frame */
+
+                       if (!stackmap_get_append_frame(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+               else if (frame_type == FRAME_TYPE_FULL_FRAME) {
+                       /* full_frame */
+
+                       if (!stackmap_get_full_frame(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+       }
+
+       /* store stack map in method structure */
+
+#if 0
+       /* currently not used */
+
+       m->stack_map = stack_map;
+#endif
+
+       return true;
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/vm/stackmap.h b/src/vm/stackmap.h
new file mode 100644 (file)
index 0000000..e86c743
--- /dev/null
@@ -0,0 +1,237 @@
+/* src/vm/stackmap.h - class attribute StackMapTable
+
+   Copyright (C) 2006 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
+   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
+   Institut f. Computersprachen - TU Wien
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Contact: cacao@cacaojvm.org
+
+   Authors: Christian Thalinger
+
+   $Id: utf8.h 5920 2006-11-05 21:23:09Z twisti $
+
+*/
+
+
+#ifndef _STACKMAP_H
+#define _STACKMAP_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct stack_map_t                       stack_map_t;
+typedef union  stack_map_frame_t                 stack_map_frame_t;
+typedef struct same_locals_1_stack_item_frame_t  same_locals_1_stack_item_frame_t;
+typedef struct same_locals_1_stack_item_frame_extended_t same_locals_1_stack_item_frame_extended_t;
+typedef struct chop_frame_t                      chop_frame_t;
+typedef struct same_frame_extended_t             same_frame_extended_t;
+typedef struct append_frame_t                    append_frame_t;
+typedef struct full_frame_t                      full_frame_t;
+
+typedef union  verification_type_info_t          verification_type_info_t;
+typedef struct Top_variable_info_t                  Top_variable_info_t;
+typedef struct Integer_variable_info_t           Integer_variable_info_t;
+typedef struct Float_variable_info_t             Float_variable_info_t;
+typedef struct Long_variable_info_t              Long_variable_info_t;
+typedef struct Double_variable_info_t            Double_variable_info_t;
+typedef struct Null_variable_info_t              Null_variable_info_t;
+typedef struct UninitializedThis_variable_info_t UninitializedThis_variable_info_t;
+typedef struct Object_variable_info_t            Object_variable_info_t;
+typedef struct Uninitialized_variable_info_t     Uninitialized_variable_info_t;
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/method.h"
+
+
+/* verification_type_info *****************************************************/
+
+#define ITEM_Top                  0
+#define ITEM_Integer              1
+#define ITEM_Float                2
+#define ITEM_Double               3
+#define ITEM_Long                 4
+#define ITEM_Null                 5
+#define ITEM_UninitializedThis    6
+#define ITEM_Object               7
+#define ITEM_Uninitialized        8
+
+struct Top_variable_info_t {
+       u1 tag;
+};
+
+struct Integer_variable_info_t {
+       u1 tag;
+};
+
+struct Float_variable_info_t {
+       u1 tag;
+};
+
+struct Long_variable_info_t {
+       u1 tag;
+};
+
+struct Double_variable_info_t {
+       u1 tag;
+};
+
+struct Null_variable_info_t {
+       u1 tag;
+};
+
+struct UninitializedThis_variable_info_t {
+       u1 tag;
+};
+
+struct Object_variable_info_t {
+       u1 tag;
+       u2 cpool_index;
+};
+
+struct Uninitialized_variable_info_t {
+       u1 tag;
+       u2 offset;
+};
+
+union verification_type_info_t {
+       u1 tag;
+       Top_variable_info_t                   Top_variable_info;
+       Integer_variable_info_t           Integer_variable_info;
+       Float_variable_info_t             Float_variable_info;
+       Long_variable_info_t              Long_variable_info;
+       Double_variable_info_t            Double_variable_info;
+       Null_variable_info_t              Null_variable_info;
+       UninitializedThis_variable_info_t UninitializedThis_variable_info;
+       Object_variable_info_t            Object_variable_info;
+       Uninitialized_variable_info_t     Uninitialized_variable_info;
+};
+
+
+/* stack_map_t ****************************************************************/
+
+struct stack_map_t {
+       u2                 attribute_name_index;
+       u4                 attribute_length;
+       u2                 number_of_entries;
+       stack_map_frame_t *entries;
+};
+
+
+/* same_locals_1_stack_item_frame_t *******************************************/
+
+struct same_locals_1_stack_item_frame_t {
+       u1                       frame_type;
+       verification_type_info_t stack[1];
+};
+
+
+/* same_locals_1_stack_item_frame_extended_t **********************************/
+
+struct same_locals_1_stack_item_frame_extended_t {
+       u1                       frame_type;
+       u2                       offset_delta;
+       verification_type_info_t stack[1];
+};
+
+
+/* chop_frame_t ***************************************************************/
+
+struct chop_frame_t {
+       u1 frame_type;
+       u2 offset_delta;
+};
+
+
+/* same_frame_extended_t ******************************************************/
+
+struct same_frame_extended_t {
+       u1 frame_type;
+       u2 offset_delta;
+};
+
+
+/* append_frame_t *************************************************************/
+
+struct append_frame_t {
+       u1                        frame_type;
+       u2                        offset_delta;
+       verification_type_info_t *locals;
+};
+
+
+/* full_frame_t ***************************************************************/
+
+struct full_frame_t {
+       u1                        frame_type;
+       u2                        offset_delta;
+       u2                        number_of_locals;
+       verification_type_info_t *locals;
+       u2                        number_of_stack_items;
+       verification_type_info_t *stack;
+};
+
+
+/* stack_map_frame_t **********************************************************/
+
+#define FRAME_TYPE_SAME                                 63   /* 0-63          */
+#define FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM             127  /* 0-127         */
+#define FRAME_TYPE_RESERVED                             246  /* 128-246       */
+#define FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM_EXTENDED    247  /* 247           */
+#define FRAME_TYPE_CHOP                                 250  /* 248-250       */
+#define FRAME_TYPE_SAME_FRAME_EXTENDED                  251  /* 251           */
+#define FRAME_TYPE_APPEND                               254  /* 252-254       */
+#define FRAME_TYPE_FULL_FRAME                           255  /* 255           */
+
+union stack_map_frame_t {
+       u1                                        frame_type;
+       same_locals_1_stack_item_frame_t          same_locals_1_stack_item_frame;
+       same_locals_1_stack_item_frame_extended_t same_locals_1_stack_item_frame_extended;
+       chop_frame_t                              chop_frame;
+       same_frame_extended_t                     same_frame_extended;
+       append_frame_t                            append_frame;
+       full_frame_t                              full_frame;
+};
+
+
+/* function prototypes ********************************************************/
+
+bool stackmap_load_attribute_stackmaptable(classbuffer *cb, methodinfo *m);
+
+#endif /* _STACKMAP_H */
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
index e88f6bd728165103822d5c415e9fd20ddbb6eb46..0f142ea3f1946bd590a488be919e72374d48a83b 100644 (file)
@@ -26,7 +26,7 @@
 
    Authors: Christian Thalinger
 
-   $Id: statistics.c 6080 2006-11-28 22:28:52Z twisti $
+   $Id: statistics.c 6216 2006-12-18 18:21:37Z twisti $
 
 */
 
@@ -76,6 +76,8 @@ s4 size_fieldinfo  = 0;
 s4 size_methodinfo = 0;
 s4 size_codeinfo   = 0;
 
+s4 size_stack_map  = 0;
+
 int count_const_pool_len = 0;
 int count_classref_len = 0;
 int count_parsed_desc_len = 0;
@@ -524,7 +526,8 @@ void print_stats(void)
        log_println("Size of native stubs:       %10.3f kB", (float) count_nstub_len / 1024);
        log_println("Size of utf:                %10.3f kB", (float) count_utf_len / 1024);
        log_println("Size of VMCode:             %10.3f kB", (float) count_vmcode_len / 1024);
-       log_println("Size of exception tables:   %10.3f kB\n", (float) count_extable_len / 1024);
+       log_println("Size of exception tables:   %10.3f kB", (float) count_extable_len / 1024);
+        log_println("size of stack map:          %10.3f kb\n", (float) size_stack_map / 1024);
 
        dolog("Number of class loads:    %6d", count_class_loads);
        dolog("Number of class inits:    %6d", count_class_inits);
index fbe035a9eb877a6e9495dff2223604311c64d916..a19e78862dc4131a203d95dd04424f79817be695 100644 (file)
@@ -26,7 +26,7 @@
 
    Authors: Christian Thalinger
 
-   $Id: statistics.h 6080 2006-11-28 22:28:52Z twisti $
+   $Id: statistics.h 6216 2006-12-18 18:21:37Z twisti $
 
 */
 
@@ -98,6 +98,8 @@ extern s4 size_fieldinfo;
 extern s4 size_methodinfo;
 extern s4 size_codeinfo;
 
+extern s4 size_stack_map;
+
 extern int count_const_pool_len;
 extern int count_classref_len;
 extern int count_parsed_desc_len;
index 4c65b583598801b950d8227a8a87118ba1998a78..63a26a8b63cf60fa12334cc035c7c06027a6003c 100644 (file)
    Contact: cacao@cacaojvm.org
 
    Authors: Reinhard Grafl
-
-   Changes: Mark Probst
+            Mark Probst
             Andreas Krall
             Christian Thalinger
-                       Edwin Steiner
+            Edwin Steiner
 
-   $Id: utf8.c 5920 2006-11-05 21:23:09Z twisti $
+   $Id: utf8.c 6216 2006-12-18 18:21:37Z twisti $
 
 */
 
@@ -121,7 +120,13 @@ utf *utf_Code;                          /* Code                               */
 utf *utf_Exceptions;                    /* Exceptions                         */
 utf *utf_LineNumberTable;               /* LineNumberTable                    */
 utf *utf_SourceFile;                    /* SourceFile                         */
+
+#if defined(ENABLE_JAVASE)
+utf *utf_EnclosingMethod;
 utf *utf_Signature;
+utf *utf_RuntimeVisibleAnnotations;
+utf *utf_StackMapTable;
+#endif
 
 utf *utf_init;                          /* <init>                             */
 utf *utf_clinit;                        /* <clinit>                           */
@@ -268,7 +273,13 @@ bool utf8_init(void)
        utf_Exceptions                 = utf_new_char("Exceptions");
        utf_LineNumberTable            = utf_new_char("LineNumberTable");
        utf_SourceFile                 = utf_new_char("SourceFile");
+
+#if defined(ENABLE_JAVASE)
+       utf_EnclosingMethod            = utf_new_char("EnclosingMethod");
        utf_Signature                  = utf_new_char("Signature");
+       utf_RuntimeVisibleAnnotations  = utf_new_char("RuntimeVisibleAnnotations");
+       utf_StackMapTable              = utf_new_char("StackMapTable");
+#endif
 
        utf_init                           = utf_new_char("<init>");
        utf_clinit                         = utf_new_char("<clinit>");
index f58106510f00e1901478e8cb09d06f6409869aa3..acc5c14d2b347bfe19ef04da6ecce8dfbb8e9253 100644 (file)
    Contact: cacao@cacaojvm.org
 
    Authors: Christian Thalinger
+            Edwin Steiner
 
-   Changes: Edwin Steiner
-
-   $Id: utf8.h 5920 2006-11-05 21:23:09Z twisti $
+   $Id: utf8.h 6216 2006-12-18 18:21:37Z twisti $
 
 */
 
@@ -114,7 +113,13 @@ extern utf *utf_Code;
 extern utf *utf_Exceptions;
 extern utf *utf_LineNumberTable;
 extern utf *utf_SourceFile;
+
+#if defined(ENABLE_JAVASE)
+extern utf *utf_EnclosingMethod;
 extern utf *utf_Signature;
+extern utf *utf_RuntimeVisibleAnnotations;
+extern utf *utf_StackMapTable;
+#endif
 
 extern utf *utf_init;
 extern utf *utf_clinit;