* src/vm/method.hpp (methodinfo): Added localvarcount and localvars field.
* src/vm/utf8.c (utf_LocalVariableTable): Added global variable
* src/vm/utf8.h: Likewise.
} line_number_table[line_number_table_length];
}
+ LocalVariableTable_attribute {
+ u2 attribute_name_index;
+ u4 attribute_length;
+ u2 local_variable_table_length;
+ {
+ u2 start_pc;
+ u2 length;
+ u2 name_index;
+ u2 descriptor_index;
+ u2 index;
+ } local_variable_table[local_variable_table_length];
+ }
+
*******************************************************************************/
bool method_load(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
if (!stackmap_load_attribute_stackmaptable(cb, m))
return false;
}
-#endif
+# if defined(ENABLE_JVMTI)
+ else if (code_attribute_name == utf_LocalVariableTable) {
+ /* LocalVariableTable */
+
+ if (m->localvars != NULL) {
+ exceptions_throw_classformaterror(c, "Multiple LocalVariableTable attributes");
+ return false;
+ }
+
+ if (!suck_check_classbuffer_size(cb, 4 + 2))
+ return false;
+
+ // Attribute length.
+ (void) suck_u4(cb);
+
+ m->localvarcount = suck_u2(cb);
+
+ if (!suck_check_classbuffer_size(cb, 10 * m->localvarcount))
+ return false;
+
+ m->localvars = MNEW(localvarinfo, m->localvarcount);
+
+ for (l = 0; l < m->localvarcount; l++) {
+ m->localvars[l].start_pc = suck_u2(cb);
+ m->localvars[l].length = suck_u2(cb);
+
+ uint16_t name_index = suck_u2(cb);
+ if (!(m->localvars[l].name = (utf*) class_getconstant(c, name_index, CONSTANT_Utf8)))
+ return false;
+
+ uint16_t descriptor_index = suck_u2(cb);
+ if (!(m->localvars[l].descriptor = (utf*) class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
+ return false;
+
+ m->localvars[l].index = suck_u2(cb);
+
+ // XXX Check if index is in range.
+ // XXX Check if index already taken.
+ }
+ }
+# endif /* defined(ENABLE_JVMTI) */
+#endif /* defined(ENABLE_JAVASE) */
else {
/* unknown code attribute */
return false;
}
-#if defined(ENABLE_ANNOTATIONS)
+# if defined(ENABLE_ANNOTATIONS)
else if (attribute_name == utf_RuntimeVisibleAnnotations) {
/* RuntimeVisibleAnnotations */
if (!annotation_load_method_attribute_runtimevisibleannotations(cb, m))
if (!annotation_load_method_attribute_annotationdefault(cb, m))
return false;
}
-#endif
+# endif
#endif
else {
/* unknown attribute */
typedef struct methodinfo methodinfo;
typedef struct raw_exception_entry raw_exception_entry;
-typedef struct lineinfo lineinfo;
+typedef struct lineinfo lineinfo;
+typedef struct localvarinfo localvarinfo;
typedef struct method_assumption method_assumption;
typedef struct method_worklist method_worklist;
typedef struct codeinfo codeinfo;
#endif
methoddesc *parseddesc; /* parsed descriptor */
-
+
classinfo *clazz; /* class, the method belongs to */
s4 vftblindex; /* index of method in virtual function */
/* table (if it is a virtual method) */
u2 linenumbercount; /* number of linenumber attributes */
lineinfo *linenumbers; /* array of lineinfo items */
+#if defined(ENABLE_JAVASE) && defined(ENABLE_JVMTI)
+ uint16_t localvarcount; /* number of local variable attributes */
+ localvarinfo* localvars; /* array of localvarinfo items */
+#endif
+
u1 *stubroutine; /* stub for compiling or calling natives */
codeinfo *code; /* current code of this method */
};
+/* localvarinfo ***************************************************************/
+
+struct localvarinfo {
+ uint16_t start_pc;
+ uint16_t length;
+ utf* name;
+ utf* descriptor;
+ uint16_t index;
+};
+
+
/* global variables ***********************************************************/
extern methodinfo *method_java_lang_reflect_Method_invoke;
utf *utf_Signature;
utf *utf_StackMapTable;
-#if defined(ENABLE_ANNOTATIONS)
+# if defined(ENABLE_JVMTI)
+utf *utf_LocalVariableTable;
+# endif
+
+# if defined(ENABLE_ANNOTATIONS)
utf *utf_RuntimeVisibleAnnotations; /* RuntimeVisibleAnnotations */
utf *utf_RuntimeInvisibleAnnotations; /* RuntimeInvisibleAnnotations */
utf *utf_RuntimeVisibleParameterAnnotations; /* RuntimeVisibleParameterAnnotations */
utf *utf_RuntimeInvisibleParameterAnnotations; /* RuntimeInvisibleParameterAnnotations */
utf *utf_AnnotationDefault; /* AnnotationDefault */
-#endif
+# endif
#endif
utf *utf_init; /* <init> */
utf_Signature = utf_new_char("Signature");
utf_StackMapTable = utf_new_char("StackMapTable");
+# if defined(ENABLE_JVMTI)
+ utf_LocalVariableTable = utf_new_char("LocalVariableTable");
+# endif
+
# if defined(ENABLE_ANNOTATIONS)
utf_RuntimeVisibleAnnotations = utf_new_char("RuntimeVisibleAnnotations");
utf_RuntimeInvisibleAnnotations = utf_new_char("RuntimeInvisibleAnnotations");
extern utf *utf_Signature;
extern utf *utf_StackMapTable;
-#if defined(ENABLE_ANNOTATIONS)
+# if defined(ENABLE_JVMTI)
+extern utf *utf_LocalVariableTable;
+# endif
+
+# if defined(ENABLE_ANNOTATIONS)
extern utf *utf_RuntimeVisibleAnnotations;
extern utf *utf_RuntimeInvisibleAnnotations;
extern utf *utf_RuntimeVisibleParameterAnnotations;
extern utf *utf_RuntimeInvisibleParameterAnnotations;
extern utf *utf_AnnotationDefault;
-#endif
+# endif
#endif
extern utf *utf_init;