(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.
##
## 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
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
libvmcore_la_SOURCES = \
access.c \
access.h \
- $(ANNOTATION_OBJ) \
+ $(ANNOTATION_SOURCES) \
builtin.c \
builtin.h \
builtintable.inc \
resolve.h \
$(RT_TIMING_OBJ) \
rt-timing.h \
- $(STATISTICS_OBJ) \
+ $(STATISTICS_SOURCES) \
signal.c \
signallocal.h \
+ $(STACKMAP_SOURCES) \
string.c \
stringlocal.h \
suck.c \
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 $
*/
#include "vm/resolve.h"
#include "vm/statistics.h"
#include "vm/stringlocal.h"
+#include "vm/suck.h"
#include "vm/utf8.h"
}
+/* 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.
/* 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;
}
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;
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 $
*/
/* 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
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"
}
-/* 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;
}
}
+/* 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
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;
}
}
}
-/* 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;
/* 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;
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;
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,
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;
}
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))
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;
}
}
-/* 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
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;
}
/* 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
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 $
*/
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);
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 $
*/
#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"
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 */
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 $
*/
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);
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */
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 $
*/
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;
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);
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 $
*/
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;
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 $
*/
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> */
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>");
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 $
*/
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;