* src/vm/class.h: Likewise.
* src/vm/class.cpp: New file.
* src/vm/class.hpp: Likewise.
* src/native/jvmti/jvmti.c,
src/native/native.hpp,
src/native/vm/gnuclasspath/gnu_classpath_VMStackWalker.cpp,
src/native/vm/gnuclasspath/gnu_java_lang_management_VMMemoryMXBeanImpl.cpp,
src/native/vm/gnuclasspath/java_lang_VMClass.cpp,
src/native/vm/gnuclasspath/java_lang_VMClassLoader.cpp,
src/native/vm/gnuclasspath/java_lang_reflect_VMMethod.cpp,
src/native/vm/gnuclasspath/sun_reflect_ConstantPool.cpp,
src/native/vm/nativevm.cpp,
src/threads/thread.cpp,
src/toolbox/logging.h,
src/vm/Makefile.am,
src/vm/access.c,
src/vm/access.h,
src/vm/annotation.c,
src/vm/annotation.h,
src/vm/classcache.h,
src/vm/descriptor.h,
src/vm/exceptions.cpp,
src/vm/field.cpp,
src/vm/field.hpp,
src/vm/globals.cpp,
src/vm/globals.hpp,
src/vm/initialize.cpp,
src/vm/initialize.hpp,
src/vm/javaobjects.hpp,
src/vm/jit/alpha/patcher.c,
src/vm/jit/arm/patcher.c,
src/vm/jit/builtin.cpp,
src/vm/jit/i386/patcher.c,
src/vm/jit/inline/inline.c,
src/vm/jit/intrp/asmpart.c,
src/vm/jit/intrp/codegen.c,
src/vm/jit/intrp/intrp.h,
src/vm/jit/intrp/patcher.c,
src/vm/jit/jit.cpp,
src/vm/jit/m68k/patcher.c,
src/vm/jit/mips/codegen.c,
src/vm/jit/mips/patcher.c,
src/vm/jit/optimizing/bytecode_escape.c,
src/vm/jit/optimizing/escape.c,
src/vm/jit/optimizing/profile.c,
src/vm/jit/powerpc/patcher.c,
src/vm/jit/powerpc64/patcher.c,
src/vm/jit/s390/patcher.c,
src/vm/jit/sparc64/patcher.c,
src/vm/jit/stacktrace.cpp,
src/vm/jit/stacktrace.hpp,
src/vm/jit/verify/typeinfo.c,
src/vm/jit/x86_64/patcher.c,
src/vm/linker.c,
src/vm/linker.h,
src/vm/loader.hpp,
src/vm/method.c,
src/vm/primitive.cpp,
src/vm/primitive.hpp,
src/vm/properties.cpp,
src/vm/references.h,
src/vm/resolve.hpp,
src/vm/stackmap.c,
src/vm/statistics.c,
src/vm/suck.hpp,
src/vm/vftbl.hpp,
src/vm/vm.cpp,
src/vm/zip.h: Adapted to above changes.
--HG--
rename : src/vm/class.c => src/vm/class.cpp
rename : src/vm/class.h => src/vm/class.hpp
#include "vm/loader.hpp"
#include "vm/jit/builtin.hpp"
#include "vm/jit/asmpart.h"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/classcache.h"
#include "mm/gc.hpp"
#include "toolbox/logging.h"
#include "native/jni.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "vm/loader.hpp"
#include "vm/method.h"
# include "native/vm/include/gnu_classpath_VMStackWalker.h"
#endif
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "vm/utf8.h"
#endif
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "vm/loader.hpp" /* XXX only for load_class_bootstrap */
#include "vm/options.h"
# include "native/vm/include/java_lang_VMClass.h"
#endif
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/exceptions.hpp"
#include "vm/globals.hpp"
#include "vm/initialize.hpp"
#endif
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/classcache.h"
#include "vm/exceptions.hpp"
#include "vm/globals.hpp"
#include "vm/access.h"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/exceptions.hpp"
#include "vm/global.h"
#include "vm/globals.hpp"
#include "toolbox/logging.h"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/exceptions.hpp"
#include "vm/javaobjects.hpp"
#include "vm/resolve.hpp"
#include "native/vm/nativevm.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/initialize.hpp"
#include "vm/method.h"
#include "vm/options.h"
#include "threads/thread.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/exceptions.hpp"
#include "vm/globals.hpp"
#include "vm/javaobjects.hpp"
#include <stdio.h>
#include <stdarg.h>
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/method.h"
#include "vm/utf8.h"
array.cpp \
array.hpp \
$(ASSERTION_SOURCES) \
- class.c \
- class.h \
+ class.cpp \
+ class.hpp \
classcache.c \
classcache.h \
$(CYCLES_STATS_SOURCES) \
#include "vm/access.h"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/exceptions.hpp"
#include "vm/field.hpp"
#include "vm/globals.hpp"
extern "C" {
#endif
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/field.hpp"
#include "vm/global.h"
#include "vm/method.h"
#include "vm/annotation.h"
#include "vm/array.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/loader.hpp"
#include "vm/primitive.hpp"
#include "vm/suck.hpp"
#include "vm/types.h"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/field.hpp"
#include "vm/global.h"
#include "vm/loader.hpp"
+++ /dev/null
-/* src/vm/class.c - class related functions
-
- Copyright (C) 1996-2005, 2006, 2007, 2008
- CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
- 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.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "vm/types.h"
-
-#include "arch.h"
-
-#include "mm/memory.h"
-
-#include "native/llni.h"
-
-#include "threads/lock.hpp"
-#include "threads/mutex.hpp"
-
-#include "toolbox/logging.h"
-
-#include "vm/array.hpp"
-#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
-#include "vm/classcache.h"
-#include "vm/exceptions.hpp"
-#include "vm/global.h"
-#include "vm/globals.hpp"
-#include "vm/javaobjects.hpp"
-#include "vm/linker.h"
-#include "vm/loader.hpp"
-#include "vm/options.h"
-#include "vm/resolve.hpp"
-
-#if defined(ENABLE_STATISTICS)
-# include "vm/statistics.h"
-#endif
-
-#include "vm/suck.hpp"
-#include "vm/utf8.h"
-
-#include "vm/jit/asmpart.h"
-
-
-/* class_set_packagename *******************************************************
-
- Derive the package name from the class name and store it in the
- struct.
-
- An internal package name consists of the package name plus the
- trailing '/', e.g. "java/lang/".
-
- For classes in the unnamed package, the package name is set to
- NULL.
-
-*******************************************************************************/
-
-void class_set_packagename(classinfo *c)
-{
- char *p;
- char *start;
-
- p = UTF_END(c->name) - 1;
- start = c->name->text;
-
- if (c->name->text[0] == '[') {
- /* Set packagename of arrays to the element's package. */
-
- for (; *start == '['; start++);
-
- /* Skip the 'L' in arrays of references. */
-
- if (*start == 'L')
- start++;
- }
-
- /* Search for last '/'. */
-
- for (; (p > start) && (*p != '/'); --p);
-
- /* If we found a '/' we set the package name plus the trailing
- '/'. Otherwise we set the packagename to NULL. */
-
- if (p > start)
- c->packagename = utf_new(start, p - start + 1);
- else
- c->packagename = NULL;
-}
-
-
-/* class_create_classinfo ******************************************************
-
- Create a new classinfo struct. The class name is set to the given utf *,
- most other fields are initialized to zero.
-
- Note: classname may be NULL. In this case a not-yet-named classinfo is
- created. The name must be filled in later and class_set_packagename
- must be called after that.
-
-*******************************************************************************/
-
-classinfo *class_create_classinfo(utf *classname)
-{
- classinfo *c;
-
-#if defined(ENABLE_STATISTICS)
- if (opt_stat)
- size_classinfo += sizeof(classinfo);
-#endif
-
- /* we use a safe name for temporarily unnamed classes */
-
- if (classname == NULL)
- classname = utf_not_named_yet;
-
-#if !defined(NDEBUG)
- if (initverbose)
- log_message_utf("Creating class: ", classname);
-#endif
-
-#if !defined(ENABLE_GC_BOEHM)
- c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
- /*c = NEW(classinfo);
- MZERO(c, classinfo, 1);*/
-#else
- c = GCNEW_UNCOLLECTABLE(classinfo, 1);
- /* GCNEW_UNCOLLECTABLE clears the allocated memory */
-#endif
-
- c->name = classname;
-
- /* Set the header.vftbl of all loaded classes to the one of
- java.lang.Class, so Java code can use a class as object. */
-
- if (class_java_lang_Class != NULL)
- if (class_java_lang_Class->vftbl != NULL)
- c->object.header.vftbl = class_java_lang_Class->vftbl;
-
-#if defined(ENABLE_JAVASE)
- /* check if the class is a reference class and flag it */
-
- if (classname == utf_java_lang_ref_SoftReference) {
- c->flags |= ACC_CLASS_REFERENCE_SOFT;
- }
- else if (classname == utf_java_lang_ref_WeakReference) {
- c->flags |= ACC_CLASS_REFERENCE_WEAK;
- }
- else if (classname == utf_java_lang_ref_PhantomReference) {
- c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
- }
-#endif
-
- if (classname != utf_not_named_yet)
- class_set_packagename(c);
-
- Lockword_init(&(c->object.header.lockword));
-
- return c;
-}
-
-
-/* class_postset_header_vftbl **************************************************
-
- Set the header.vftbl of all classes created before java.lang.Class
- was linked. This is necessary that Java code can use a class as
- object.
-
-*******************************************************************************/
-
-void class_postset_header_vftbl(void)
-{
- classinfo *c;
- u4 slot;
- classcache_name_entry *nmen;
- classcache_class_entry *clsen;
-
- assert(class_java_lang_Class);
-
- for (slot = 0; slot < hashtable_classcache.size; slot++) {
- nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
-
- for (; nmen; nmen = nmen->hashlink) {
- /* iterate over all class entries */
-
- for (clsen = nmen->classes; clsen; clsen = clsen->next) {
- c = clsen->classobj;
-
- /* now set the the vftbl */
-
- if (c->object.header.vftbl == NULL)
- c->object.header.vftbl = class_java_lang_Class->vftbl;
- }
- }
- }
-}
-
-/* class_define ****************************************************************
-
- Calls the loader and defines a class in the VM.
-
-*******************************************************************************/
-
-classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
-{
- classinfo *c;
- classinfo *r;
- classbuffer *cb;
-
- if (name != NULL) {
- /* check if this class has already been defined */
-
- c = classcache_lookup_defined_or_initiated(cl, name);
-
- if (c != NULL) {
- exceptions_throw_linkageerror("duplicate class definition: ", c);
- return NULL;
- }
- }
-
- /* create a new classinfo struct */
-
- c = class_create_classinfo(name);
-
-#if defined(ENABLE_STATISTICS)
- /* measure time */
-
- if (opt_getloadingtime)
- loadingtime_start();
-#endif
-
- /* build a classbuffer with the given data */
-
- cb = NEW(classbuffer);
-
- cb->clazz = c;
- cb->size = length;
- cb->data = data;
- cb->pos = cb->data;
-
- /* preset the defining classloader */
-
- c->classloader = cl;
-
- /* load the class from this buffer */
-
- r = load_class_from_classbuffer(cb);
-
- /* free memory */
-
- FREE(cb, classbuffer);
-
-#if defined(ENABLE_STATISTICS)
- /* measure time */
-
- if (opt_getloadingtime)
- loadingtime_stop();
-#endif
-
- if (r == NULL) {
- /* If return value is NULL, we had a problem and the class is
- not loaded. Now free the allocated memory, otherwise we
- could run into a DOS. */
-
- class_free(c);
-
- return NULL;
- }
-
-#if defined(ENABLE_JAVASE)
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
- /* Store the protection domain. */
-
- c->protectiondomain = pd;
-# endif
-#endif
-
- /* Store the newly defined class in the class cache. This call
- also checks whether a class of the same name has already been
- defined by the same defining loader, and if so, replaces the
- newly created class by the one defined earlier. */
-
- /* Important: The classinfo given to classcache_store must be
- fully prepared because another thread may return
- this pointer after the lookup at to top of this
- function directly after the class cache lock has
- been released. */
-
- c = classcache_store(cl, c, true);
-
- return c;
-}
-
-
-/* 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->clazz;
-
- /* 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;
- }
-
-*******************************************************************************/
-
-#if defined(ENABLE_JAVASE)
-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->clazz;
-
- /* 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;
-}
-#endif /* defined(ENABLE_JAVASE) */
-
-
-/* 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;
- uint16_t attributes_count;
- uint16_t attribute_name_index;
- utf *attribute_name;
- innerclassinfo *info;
- classref_or_classinfo inner;
- classref_or_classinfo outer;
- utf *name;
- uint16_t flags;
- int i, j;
-
- c = cb->clazz;
-
- /* 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. */
-
- info = c->innerclass + j;
-
- inner.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
- outer.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
- name = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
- flags = suck_u2(cb);
-
- /* If the current inner-class is the currently loaded
- class check for some special flags. */
-
- if (inner.ref->name == c->name) {
- /* If an inner-class is not a member, its
- outer-class is NULL. */
-
- if (outer.ref != NULL) {
- c->flags |= ACC_CLASS_MEMBER;
-
- /* A member class doesn't have an
- EnclosingMethod attribute, so set the
- enclosing-class to be the same as the
- declaring-class. */
-
- c->declaringclass = outer;
- c->enclosingclass = outer;
- }
-
- /* If an inner-class is anonymous, its name is
- NULL. */
-
- if (name == NULL)
- c->flags |= ACC_CLASS_ANONYMOUS;
- }
-
- info->inner_class = inner;
- info->outer_class = outer;
- info->name = name;
- info->flags = flags;
- }
- }
- 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;
- }
-#endif
-
-#if defined(ENABLE_ANNOTATIONS)
- else if (attribute_name == utf_RuntimeVisibleAnnotations) {
- /* RuntimeVisibleAnnotations */
- if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
- return false;
- }
- else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
- /* RuntimeInvisibleAnnotations */
- if (!annotation_load_class_attribute_runtimeinvisibleannotations(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.
-
-*******************************************************************************/
-
-static void class_freecpool(classinfo *c)
-{
- u4 idx;
- u4 tag;
- void* info;
-
- if (c->cptags && c->cpinfos) {
- for (idx = 0; idx < c->cpcount; idx++) {
- tag = c->cptags[idx];
- info = c->cpinfos[idx];
-
- if (info != NULL) {
- switch (tag) {
- case CONSTANT_Fieldref:
- case CONSTANT_Methodref:
- case CONSTANT_InterfaceMethodref:
- FREE(info, constant_FMIref);
- break;
- case CONSTANT_Integer:
- FREE(info, constant_integer);
- break;
- case CONSTANT_Float:
- FREE(info, constant_float);
- break;
- case CONSTANT_Long:
- FREE(info, constant_long);
- break;
- case CONSTANT_Double:
- FREE(info, constant_double);
- break;
- case CONSTANT_NameAndType:
- FREE(info, constant_nameandtype);
- break;
- }
- }
- }
- }
-
- if (c->cptags)
- MFREE(c->cptags, u1, c->cpcount);
-
- if (c->cpinfos)
- MFREE(c->cpinfos, void*, c->cpcount);
-}
-
-
-/* class_getconstant ***********************************************************
-
- Retrieves the value at position 'pos' of the constantpool of a
- class. If the type of the value is other than 'ctype', an error is
- thrown.
-
-*******************************************************************************/
-
-void* 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)) {
- exceptions_throw_classformaterror(c, "Illegal constant pool index");
- return NULL;
- }
-
- return c->cpinfos[pos];
-}
-
-
-/* innerclass_getconstant ******************************************************
-
- Like class_getconstant, but if cptags is ZERO, null is returned.
-
-*******************************************************************************/
-
-void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
-{
- /* invalid position in constantpool */
-
- if (pos >= c->cpcount) {
- exceptions_throw_classformaterror(c, "Illegal constant pool index");
- return NULL;
- }
-
- /* constantpool entry of type 0 */
-
- if (c->cptags[pos] == 0)
- return NULL;
-
- /* check type of constantpool entry */
-
- if (c->cptags[pos] != ctype) {
- exceptions_throw_classformaterror(c, "Illegal constant pool index");
- return NULL;
- }
-
- return c->cpinfos[pos];
-}
-
-
-/* class_free ******************************************************************
-
- Frees all resources used by the class.
-
-*******************************************************************************/
-
-void class_free(classinfo *c)
-{
- s4 i;
- vftbl_t *v;
-
- class_freecpool(c);
-
- if (c->interfaces != NULL)
- MFREE(c->interfaces, classinfo*, c->interfacescount);
-
- if (c->fields) {
- for (i = 0; i < c->fieldscount; i++)
- field_free(&(c->fields[i]));
- MFREE(c->fields, fieldinfo, c->fieldscount);
- }
-
- if (c->methods) {
- for (i = 0; i < c->methodscount; i++)
- method_free(&(c->methods[i]));
- MFREE(c->methods, methodinfo, c->methodscount);
- }
-
- if ((v = c->vftbl) != NULL) {
- if (v->arraydesc)
- mem_free(v->arraydesc,sizeof(arraydescriptor));
-
- for (i = 0; i < v->interfacetablelength; i++) {
- MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
- }
- MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
-
- i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
- sizeof(methodptr*) * (v->interfacetablelength -
- (v->interfacetablelength > 0));
- v = (vftbl_t*) (((methodptr*) v) -
- (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
- mem_free(v, i);
- }
-
- if (c->innerclass)
- MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
-
- /* if (c->classvftbl)
- mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
-
-/* GCFREE(c); */
-}
-
-
-/* get_array_class *************************************************************
-
- Returns the array class with the given name for the given
- classloader, or NULL if an exception occurred.
-
- Note: This function does eager loading.
-
-*******************************************************************************/
-
-static classinfo *get_array_class(utf *name,classloader_t *initloader,
- classloader_t *defloader,bool link)
-{
- classinfo *c;
-
- /* lookup this class in the classcache */
- c = classcache_lookup(initloader,name);
- if (!c)
- c = classcache_lookup_defined(defloader,name);
-
- if (!c) {
- /* we have to create it */
- c = class_create_classinfo(name);
- c = load_newly_created_array(c,initloader);
- if (c == NULL)
- return NULL;
- }
-
- assert(c);
- assert(c->state & CLASS_LOADED);
- assert(c->classloader == defloader);
-
- if (link && !(c->state & CLASS_LINKED))
- if (!link_class(c))
- return NULL;
-
- assert(!link || (c->state & CLASS_LINKED));
-
- return c;
-}
-
-
-/* class_array_of **************************************************************
-
- Returns an array class with the given component class. The array
- class is dynamically created if neccessary.
-
-*******************************************************************************/
-
-classinfo *class_array_of(classinfo *component, bool link)
-{
- classloader_t *cl;
- s4 namelen;
- char *namebuf;
- utf *u;
- classinfo *c;
-
- cl = component->classloader;
-
- /* Assemble the array class name */
- namelen = component->name->blength;
-
- if (component->name->text[0] == '[') {
- /* the component is itself an array */
- namebuf = MNEW(char, namelen + 1);
- namebuf[0] = '[';
- MCOPY(namebuf + 1, component->name->text, char, namelen);
- namelen++;
- }
- else {
- /* the component is a non-array class */
- namebuf = MNEW(char, namelen + 3);
- namebuf[0] = '[';
- namebuf[1] = 'L';
- MCOPY(namebuf + 2, component->name->text, char, namelen);
- namebuf[2 + namelen] = ';';
- namelen += 3;
- }
-
- u = utf_new(namebuf, namelen);
-
- MFREE(namebuf, char, namelen);
-
- c = get_array_class(u, cl, cl, link);
-
- return c;
-}
-
-
-/* class_multiarray_of *********************************************************
-
- Returns an array class with the given dimension and element class.
- The array class is dynamically created if neccessary.
-
-*******************************************************************************/
-
-classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
-{
- s4 namelen;
- char *namebuf;
- classinfo *c;
-
- if (dim < 1) {
- log_text("Invalid array dimension requested");
- assert(0);
- }
-
- /* Assemble the array class name */
- namelen = element->name->blength;
-
- if (element->name->text[0] == '[') {
- /* the element is itself an array */
- namebuf = MNEW(char, namelen + dim);
- memcpy(namebuf + dim, element->name->text, namelen);
- namelen += dim;
- }
- else {
- /* the element is a non-array class */
- namebuf = MNEW(char, namelen + 2 + dim);
- namebuf[dim] = 'L';
- memcpy(namebuf + dim + 1, element->name->text, namelen);
- namelen += (2 + dim);
- namebuf[namelen - 1] = ';';
- }
- memset(namebuf, '[', dim);
-
- utf* u = utf_new(namebuf, namelen);
-
- MFREE(namebuf, char, namelen);
-
- c = get_array_class(u,
- element->classloader,
- element->classloader,
- link);
-
- return c;
-}
-
-
-/* class_lookup_classref *******************************************************
-
- Looks up the constant_classref for a given classname in the classref
- tables of a class.
-
- IN:
- cls..............the class containing the reference
- name.............the name of the class refered to
-
- RETURN VALUE:
- a pointer to a constant_classref, or
- NULL if the reference was not found
-
-*******************************************************************************/
-
-constant_classref *class_lookup_classref(classinfo *cls, utf *name)
-{
- constant_classref *ref;
- extra_classref *xref;
- int count;
-
- assert(cls);
- assert(name);
- assert(!cls->classrefcount || cls->classrefs);
-
- /* first search the main classref table */
- count = cls->classrefcount;
- ref = cls->classrefs;
- for (; count; --count, ++ref)
- if (ref->name == name)
- return ref;
-
- /* next try the list of extra classrefs */
- for (xref = cls->extclassrefs; xref; xref = xref->next) {
- if (xref->classref.name == name)
- return &(xref->classref);
- }
-
- /* not found */
- return NULL;
-}
-
-
-/* class_get_classref **********************************************************
-
- Returns the constant_classref for a given classname.
-
- IN:
- cls..............the class containing the reference
- name.............the name of the class refered to
-
- RETURN VALUE:
- a pointer to a constant_classref (never NULL)
-
- NOTE:
- The given name is not checked for validity!
-
-*******************************************************************************/
-
-constant_classref *class_get_classref(classinfo *cls, utf *name)
-{
- constant_classref *ref;
- extra_classref *xref;
-
- assert(cls);
- assert(name);
-
- ref = class_lookup_classref(cls,name);
- if (ref)
- return ref;
-
- xref = NEW(extra_classref);
- CLASSREF_INIT(xref->classref,cls,name);
-
- xref->next = cls->extclassrefs;
- cls->extclassrefs = xref;
-
- return &(xref->classref);
-}
-
-
-/* class_get_self_classref *****************************************************
-
- Returns the constant_classref to the class itself.
-
- IN:
- cls..............the class containing the reference
-
- RETURN VALUE:
- a pointer to a constant_classref (never NULL)
-
-*******************************************************************************/
-
-constant_classref *class_get_self_classref(classinfo *cls)
-{
- /* XXX this should be done in a faster way. Maybe always make */
- /* the classref of index 0 a self reference. */
- return class_get_classref(cls,cls->name);
-}
-
-/* class_get_classref_multiarray_of ********************************************
-
- Returns an array type reference with the given dimension and element class
- reference.
-
- IN:
- dim..............the requested dimension
- dim must be in [1;255]. This is NOT checked!
- ref..............the component class reference
-
- RETURN VALUE:
- a pointer to the class reference for the array type
-
- NOTE:
- The referer of `ref` is used as the referer for the new classref.
-
-*******************************************************************************/
-
-constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
-{
- s4 namelen;
- char *namebuf;
- constant_classref *cr;
-
- assert(ref);
- assert(dim >= 1 && dim <= 255);
-
- /* Assemble the array class name */
- namelen = ref->name->blength;
-
- if (ref->name->text[0] == '[') {
- /* the element is itself an array */
- namebuf = MNEW(char, namelen + dim);
- memcpy(namebuf + dim, ref->name->text, namelen);
- namelen += dim;
- }
- else {
- /* the element is a non-array class */
- namebuf = MNEW(char, namelen + 2 + dim);
- namebuf[dim] = 'L';
- memcpy(namebuf + dim + 1, ref->name->text, namelen);
- namelen += (2 + dim);
- namebuf[namelen - 1] = ';';
- }
- memset(namebuf, '[', dim);
-
- utf* u = utf_new(namebuf, namelen);
-
- MFREE(namebuf, char, namelen);
-
- cr = class_get_classref(ref->referer, u);
-
- return cr;
-}
-
-
-/* class_get_classref_component_of *********************************************
-
- Returns the component classref of a given array type reference
-
- IN:
- ref..............the array type reference
-
- RETURN VALUE:
- a reference to the component class, or
- NULL if `ref` is not an object array type reference
-
- NOTE:
- The referer of `ref` is used as the referer for the new classref.
-
-*******************************************************************************/
-
-constant_classref *class_get_classref_component_of(constant_classref *ref)
-{
- s4 namelen;
- char *name;
-
- assert(ref);
-
- name = ref->name->text;
- if (*name++ != '[')
- return NULL;
-
- namelen = ref->name->blength - 1;
- if (*name == 'L') {
- name++;
- namelen -= 2;
- }
- else if (*name != '[') {
- return NULL;
- }
-
- return class_get_classref(ref->referer, utf_new(name, namelen));
-}
-
-
-/* class_findmethod ************************************************************
-
- Searches a 'classinfo' structure for a method having the given name
- and descriptor. If descriptor is NULL, it is ignored.
-
-*******************************************************************************/
-
-methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
-{
- methodinfo *m;
- s4 i;
-
- for (i = 0; i < c->methodscount; i++) {
- m = &(c->methods[i]);
-
- if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
- return m;
- }
-
- return NULL;
-}
-
-
-/* class_resolvemethod *********************************************************
-
- Searches a class and it's super classes for a method.
-
- Superinterfaces are *not* searched.
-
-*******************************************************************************/
-
-methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
-{
- methodinfo *m;
-
- while (c) {
- m = class_findmethod(c, name, desc);
-
- if (m)
- return m;
-
- /* JVM Specification bug:
-
- It is important NOT to resolve special <init> and <clinit>
- methods to super classes or interfaces; yet, this is not
- explicited in the specification. Section 5.4.3.3 should be
- updated appropriately. */
-
- if (name == utf_init || name == utf_clinit)
- return NULL;
-
- c = c->super;
- }
-
- return NULL;
-}
-
-
-/* class_resolveinterfacemethod_intern *****************************************
-
- Internally used helper function. Do not use this directly.
-
-*******************************************************************************/
-
-static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
- utf *name, utf *desc)
-{
- methodinfo *m;
- s4 i;
-
- /* try to find the method in the class */
-
- m = class_findmethod(c, name, desc);
-
- if (m != NULL)
- return m;
-
- /* No method found? Try the super interfaces. */
-
- for (i = 0; i < c->interfacescount; i++) {
- m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
-
- if (m != NULL)
- return m;
- }
-
- /* no method found */
-
- return NULL;
-}
-
-
-/* class_resolveclassmethod ****************************************************
-
- Resolves a reference from REFERER to a method with NAME and DESC in
- class C.
-
- If the method cannot be resolved the return value is NULL. If
- EXCEPT is true *exceptionptr is set, too.
-
-*******************************************************************************/
-
-methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
- classinfo *referer, bool throwexception)
-{
- classinfo *cls;
- methodinfo *m;
- s4 i;
-
-/* if (c->flags & ACC_INTERFACE) { */
-/* if (throwexception) */
-/* *exceptionptr = */
-/* new_exception(string_java_lang_IncompatibleClassChangeError); */
-/* return NULL; */
-/* } */
-
- /* try class c and its superclasses */
-
- cls = c;
-
- m = class_resolvemethod(cls, name, desc);
-
- if (m != NULL)
- goto found;
-
- /* Try the super interfaces. */
-
- for (i = 0; i < c->interfacescount; i++) {
- m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
-
- if (m != NULL)
- goto found;
- }
-
- if (throwexception)
- exceptions_throw_nosuchmethoderror(c, name, desc);
-
- return NULL;
-
- found:
- if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
- if (throwexception)
- exceptions_throw_abstractmethoderror();
-
- return NULL;
- }
-
- /* XXX check access rights */
-
- return m;
-}
-
-
-/* class_resolveinterfacemethod ************************************************
-
- Resolves a reference from REFERER to a method with NAME and DESC in
- interface C.
-
- If the method cannot be resolved the return value is NULL. If
- EXCEPT is true *exceptionptr is set, too.
-
-*******************************************************************************/
-
-methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
- classinfo *referer, bool throwexception)
-{
- methodinfo *mi;
-
- if (!(c->flags & ACC_INTERFACE)) {
- if (throwexception)
- exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
-
- return NULL;
- }
-
- mi = class_resolveinterfacemethod_intern(c, name, desc);
-
- if (mi != NULL)
- return mi;
-
- /* try class java.lang.Object */
-
- mi = class_findmethod(class_java_lang_Object, name, desc);
-
- if (mi != NULL)
- return mi;
-
- if (throwexception)
- exceptions_throw_nosuchmethoderror(c, name, desc);
-
- return NULL;
-}
-
-
-/* class_findfield *************************************************************
-
- Searches for field with specified name and type in a classinfo
- structure. If no such field is found NULL is returned.
-
-*******************************************************************************/
-
-fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
-{
- s4 i;
-
- for (i = 0; i < c->fieldscount; i++)
- if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
- return &(c->fields[i]);
-
- if (c->super != NULL)
- return class_findfield(c->super, name, desc);
-
- return NULL;
-}
-
-
-/* class_findfield_approx ******************************************************
-
- Searches in 'classinfo'-structure for a field with the specified
- name.
-
-*******************************************************************************/
-
-fieldinfo *class_findfield_by_name(classinfo* c, utf* name)
-{
- for (int32_t i = 0; i < c->fieldscount; i++) {
- fieldinfo* f = &(c->fields[i]);
-
- if (f->name == name)
- return f;
- }
-
- // Field not found.
- exceptions_throw_nosuchfielderror(c, name);
- return NULL;
-}
-
-
-/****************** Function: class_resolvefield_int ***************************
-
- This is an internally used helper function. Do not use this directly.
-
- Tries to resolve a field having the given name and type.
- If the field cannot be resolved, NULL is returned.
-
-*******************************************************************************/
-
-static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
-{
- fieldinfo *fi;
- s4 i;
-
- /* search for field in class c */
-
- for (i = 0; i < c->fieldscount; i++) {
- if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
- return &(c->fields[i]);
- }
- }
-
- /* Try super interfaces recursively. */
-
- for (i = 0; i < c->interfacescount; i++) {
- fi = class_resolvefield_int(c->interfaces[i], name, desc);
-
- if (fi != NULL)
- return fi;
- }
-
- /* Try super class. */
-
- if (c->super != NULL)
- return class_resolvefield_int(c->super, name, desc);
-
- /* not found */
-
- return NULL;
-}
-
-
-/********************* Function: class_resolvefield ***************************
-
- Resolves a reference from REFERER to a field with NAME and DESC in class C.
-
- If the field cannot be resolved, an exception is thrown and the
- return value is NULL.
-
-*******************************************************************************/
-
-fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer)
-{
- fieldinfo *fi;
-
- fi = class_resolvefield_int(c, name, desc);
-
- if (!fi) {
- exceptions_throw_nosuchfielderror(c, name);
- return NULL;
- }
-
- /* XXX check access rights */
-
- return fi;
-}
-
-
-/* class_issubclass ************************************************************
-
- Checks if sub is a descendant of super.
-
-*******************************************************************************/
-
-bool class_issubclass(classinfo *sub, classinfo *super)
-{
- classinfo *c;
-
- c = sub;
-
- for (;;) {
- /* We reached java/lang/Object and did not find the requested
- super class. */
-
- if (c == NULL)
- return false;
-
- /* We found the requested super class. */
-
- if (c == super)
- return true;
-
- c = c->super;
- }
-}
-
-
-/* class_isanysubclass *********************************************************
-
- Checks a subclass relation between two classes. Implemented
- interfaces are interpreted as super classes.
-
- Return value: 1 ... sub is subclass of super
- 0 ... otherwise
-
-*******************************************************************************/
-
-bool class_isanysubclass(classinfo *sub, classinfo *super)
-{
- uint32_t diffval;
- bool result;
-
- /* This is the trivial case. */
-
- if (sub == super)
- return true;
-
- /* Primitive classes are only subclasses of themselves. */
-
- if (class_is_primitive(sub) || class_is_primitive(super))
- return false;
-
- /* Check for interfaces. */
-
- if (super->flags & ACC_INTERFACE) {
- result = (sub->vftbl->interfacetablelength > super->index) &&
- (sub->vftbl->interfacetable[-super->index] != NULL);
- }
- else {
- /* java.lang.Object is the only super class of any
- interface. */
-
- if (sub->flags & ACC_INTERFACE)
- return (super == class_java_lang_Object);
-
- Mutex_lock(linker_classrenumber_mutex);
-
- diffval = sub->vftbl->baseval - super->vftbl->baseval;
- result = diffval <= (uint32_t) super->vftbl->diffval;
-
- Mutex_unlock(linker_classrenumber_mutex);
- }
-
- return result;
-}
-
-
-/* class_is_assignable_from ****************************************************
-
- Return whether an instance of the "from" class parameter would be
- an instance of this class "to" as well.
-
- ARGUMENTS:
- to ..... class
- from ... class
-
- RETURN:
- true .... is assignable
- false ... is not assignable
-
-*******************************************************************************/
-
-bool class_is_assignable_from(classinfo *to, classinfo *from)
-{
- if (!(to->state & CLASS_LINKED))
- if (!link_class(to))
- return false;
-
- if (!(from->state & CLASS_LINKED))
- if (!link_class(from))
- return false;
-
- return class_isanysubclass(from, to);
-}
-
-
-/* class_is_instance ***********************************************************
-
- Return if the given Java object is an instance of the given class.
-
- ARGUMENTS:
- c ... class
- h ... Java object
-
- RETURN:
- true .... is instance
- false ... is not instance
-
-*******************************************************************************/
-
-bool class_is_instance(classinfo *c, java_handle_t *h)
-{
- if (!(c->state & CLASS_LINKED))
- if (!link_class(c))
- return false;
-
- return builtin_instanceof(h, c);
-}
-
-
-/* class_get_componenttype *****************************************************
-
- Return the component class of the given class. If the given class
- is not an array, return NULL.
-
-*******************************************************************************/
-
-classinfo *class_get_componenttype(classinfo *c)
-{
- classinfo *component;
- arraydescriptor *ad;
-
- /* XXX maybe we could find a way to do this without linking. */
- /* This way should be safe and easy, however. */
-
- if (!(c->state & CLASS_LINKED))
- if (!link_class(c))
- return NULL;
-
- ad = c->vftbl->arraydesc;
-
- if (ad == NULL)
- return NULL;
-
- if (ad->arraytype == ARRAYTYPE_OBJECT)
- component = ad->componentvftbl->clazz;
- else
- component = Primitive_get_class_by_type(ad->arraytype);
-
- return component;
-}
-
-
-/* class_get_declaredclasses ***************************************************
-
- Return an array of declared classes of the given class.
-
-*******************************************************************************/
-
-java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
-{
- classref_or_classinfo inner;
- classref_or_classinfo outer;
- utf *outername;
- int declaredclasscount; /* number of declared classes */
- int pos; /* current declared class */
- java_handle_objectarray_t *oa; /* array of declared classes */
- int i;
- classinfo *ic;
-
- declaredclasscount = 0;
-
- if (!class_is_primitive(c) && !class_is_array(c)) {
- /* Determine number of declared classes. */
-
- for (i = 0; i < c->innerclasscount; i++) {
- /* Get outer-class. If the inner-class is not a member
- class, the outer-class is NULL. */
-
- outer = c->innerclass[i].outer_class;
-
- if (outer.any == NULL)
- continue;
-
- /* Check if outer-class is a classref or a real class and
- get the class name from the structure. */
-
- outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
-
- /* Outer class is this class. */
-
- if ((outername == c->name) &&
- ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
- declaredclasscount++;
- }
- }
-
- /* Allocate Class[] and check for OOM. */
-
- oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
-
- if (oa == NULL)
- return NULL;
-
- for (i = 0, pos = 0; i < c->innerclasscount; i++) {
- inner = c->innerclass[i].inner_class;
- outer = c->innerclass[i].outer_class;
-
- /* Get outer-class. If the inner-class is not a member class,
- the outer-class is NULL. */
-
- if (outer.any == NULL)
- continue;
-
- /* Check if outer_class is a classref or a real class and get
- the class name from the structure. */
-
- outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
-
- /* Outer class is this class. */
-
- if ((outername == c->name) &&
- ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
-
- ic = resolve_classref_or_classinfo_eager(inner, false);
-
- if (ic == NULL)
- return NULL;
-
- if (!(ic->state & CLASS_LINKED))
- if (!link_class(ic))
- return NULL;
-
- LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
- }
- }
-
- return oa;
-}
-
-
-/**
- * Return an array of declared constructors of the given class.
- *
- * @param c class to get the constructors of
- * @param publicOnly show only public fields
- *
- * @return array of java.lang.reflect.Constructor
- */
-#if defined(ENABLE_JAVASE)
-java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
-{
- methodinfo* m;
- java_handle_objectarray_t* oa;
- java_handle_t* rc;
- int count;
- int index;
- int i;
-
- /* Determine number of constructors. */
-
- count = 0;
-
- for (i = 0; i < c->methodscount; i++) {
- m = &(c->methods[i]);
-
- if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
- (m->name == utf_init))
- count++;
- }
-
- /* Create array of constructors. */
-
- oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
-
- if (oa == NULL)
- return NULL;
-
- /* Get the constructors and store them in the array. */
-
- for (i = 0, index = 0; i < c->methodscount; i++) {
- m = &(c->methods[i]);
-
- if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
- (m->name == utf_init)) {
- // Create a java.lang.reflect.Constructor object.
-
- rc = java_lang_reflect_Constructor_create(m);
-
- /* Store object into array. */
-
- array_objectarray_element_set(oa, index, rc);
- index++;
- }
- }
-
- return oa;
-}
-#endif
-
-
-/* class_get_declaredfields ****************************************************
-
- Return an array of declared fields of the given class.
-
- ARGUMENTS:
- c ............ class to get the fields of
- publicOnly ... show only public fields
-
- RETURN:
- array of java.lang.reflect.Field
-
-*******************************************************************************/
-
-#if defined(ENABLE_JAVASE)
-java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
-{
- java_handle_objectarray_t *oa;
- fieldinfo *f;
- java_handle_t *h;
- int count;
- int index;
- int i;
-
- /* Determine number of fields. */
-
- count = 0;
-
- for (i = 0; i < c->fieldscount; i++)
- if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
- count++;
-
- /* Create array of fields. */
-
- oa = builtin_anewarray(count, class_java_lang_reflect_Field);
-
- if (oa == NULL)
- return NULL;
-
- /* Get the fields and store them in the array. */
-
- for (i = 0, index = 0; i < c->fieldscount; i++) {
- f = &(c->fields[i]);
-
- if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
- // Create a java.lang.reflect.Field object.
-
- h = java_lang_reflect_Field_create(f);
-
- /* Store object into array. */
-
- array_objectarray_element_set(oa, index, h);
- index++;
- }
- }
-
- return oa;
-}
-#endif
-
-
-/* class_get_declaredmethods ***************************************************
-
- Return an array of declared methods of the given class.
-
- ARGUMENTS:
- c ............ class to get the methods of
- publicOnly ... show only public methods
-
- RETURN:
- array of java.lang.reflect.Method
-
-*******************************************************************************/
-
-#if defined(ENABLE_JAVASE)
-java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
-{
- java_handle_objectarray_t *oa; /* result: array of Method-objects */
- methodinfo *m; /* the current method to be represented */
- java_handle_t *h;
- int count;
- int index;
- int i;
-
- /* JOWENN: array classes do not declare methods according to mauve
- test. It should be considered, if we should return to my old
- clone method overriding instead of declaring it as a member
- function. */
-
- if (class_is_array(c))
- return builtin_anewarray(0, class_java_lang_reflect_Method);
-
- /* Determine number of methods. */
-
- count = 0;
-
- for (i = 0; i < c->methodscount; i++) {
- m = &(c->methods[i]);
-
- if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
- ((m->name != utf_init) && (m->name != utf_clinit)) &&
- !(m->flags & ACC_MIRANDA))
- count++;
- }
-
- /* Create array of methods. */
-
- oa = builtin_anewarray(count, class_java_lang_reflect_Method);
-
- if (oa == NULL)
- return NULL;
-
- /* Get the methods and store them in the array. */
-
- for (i = 0, index = 0; i < c->methodscount; i++) {
- m = &(c->methods[i]);
-
- if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
- ((m->name != utf_init) && (m->name != utf_clinit)) &&
- !(m->flags & ACC_MIRANDA)) {
- // Create java.lang.reflect.Method object.
-
- h = java_lang_reflect_Method_create(m);
-
- /* Store object into array. */
-
- array_objectarray_element_set(oa, index, h);
- index++;
- }
- }
-
- return oa;
-}
-#endif
-
-
-/* class_get_declaringclass ****************************************************
-
- If the class or interface given is a member of another class,
- return the declaring class. For array and primitive classes return
- NULL.
-
-*******************************************************************************/
-
-classinfo *class_get_declaringclass(classinfo *c)
-{
- classref_or_classinfo cr;
- classinfo *dc;
-
- /* Get declaring class. */
-
- cr = c->declaringclass;
-
- if (cr.any == NULL)
- return NULL;
-
- /* Resolve the class if necessary. */
-
- if (IS_CLASSREF(cr)) {
-/* dc = resolve_classref_eager(cr.ref); */
- dc = resolve_classref_or_classinfo_eager(cr, true);
-
- if (dc == NULL)
- return NULL;
-
- /* Store the resolved class in the class structure. */
-
- cr.cls = dc;
- }
-
- dc = cr.cls;
-
- return dc;
-}
-
-
-/* class_get_enclosingclass ****************************************************
-
- Return the enclosing class for the given class.
-
-*******************************************************************************/
-
-classinfo *class_get_enclosingclass(classinfo *c)
-{
- classref_or_classinfo cr;
- classinfo *ec;
-
- /* Get enclosing class. */
-
- cr = c->enclosingclass;
-
- if (cr.any == NULL)
- return NULL;
-
- /* Resolve the class if necessary. */
-
- if (IS_CLASSREF(cr)) {
-/* ec = resolve_classref_eager(cr.ref); */
- ec = resolve_classref_or_classinfo_eager(cr, true);
-
- if (ec == NULL)
- return NULL;
-
- /* Store the resolved class in the class structure. */
-
- cr.cls = ec;
- }
-
- ec = cr.cls;
-
- return ec;
-}
-
-
-/**
- * Return the enclosing constructor as java.lang.reflect.Constructor
- * object for the given class.
- *
- * @param c class to return the enclosing constructor for
- *
- * @return java.lang.reflect.Constructor object of the enclosing
- * constructor
- */
-#if defined(ENABLE_JAVASE)
-java_handle_t* class_get_enclosingconstructor(classinfo *c)
-{
- methodinfo* m;
- java_handle_t* rc;
-
- m = class_get_enclosingmethod_raw(c);
-
- if (m == NULL)
- return NULL;
-
- /* Check for <init>. */
-
- if (m->name != utf_init)
- return NULL;
-
- // Create a java.lang.reflect.Constructor object.
-
- rc = java_lang_reflect_Constructor_create(m);
-
- return rc;
-}
-#endif
-
-
-/* class_get_enclosingmethod ***************************************************
-
- Return the enclosing method for the given class.
-
- IN:
- c ... class to return the enclosing method for
-
- RETURN:
- methodinfo of the enclosing method
-
-*******************************************************************************/
-
-methodinfo *class_get_enclosingmethod_raw(classinfo *c)
-{
- constant_nameandtype *cn;
- classinfo *ec;
- methodinfo *m;
-
- /* get enclosing class and method */
-
- ec = class_get_enclosingclass(c);
- cn = c->enclosingmethod;
-
- /* check for enclosing class and method */
-
- if (ec == NULL)
- return NULL;
-
- if (cn == NULL)
- return NULL;
-
- /* find method in enclosing class */
-
- m = class_findmethod(ec, cn->name, cn->descriptor);
-
- if (m == NULL) {
- exceptions_throw_internalerror("Enclosing method doesn't exist");
- return NULL;
- }
-
- return m;
-}
-
-
-/**
- * Return the enclosing method as java.lang.reflect.Method object for
- * the given class.
- *
- * @param c class to return the enclosing method for
- *
- * @return java.lang.reflect.Method object of the enclosing method
- */
-#if defined(ENABLE_JAVASE)
-java_handle_t* class_get_enclosingmethod(classinfo *c)
-{
- methodinfo* m;
- java_handle_t* rm;
-
- m = class_get_enclosingmethod_raw(c);
-
- if (m == NULL)
- return NULL;
-
- /* check for <init> */
-
- if (m->name == utf_init)
- return NULL;
-
- // Create a java.lang.reflect.Method object.
-
- rm = java_lang_reflect_Method_create(m);
-
- return rm;
-}
-#endif
-
-
-/* class_get_interfaces ********************************************************
-
- Return an array of interfaces of the given class.
-
-*******************************************************************************/
-
-java_handle_objectarray_t *class_get_interfaces(classinfo *c)
-{
- classinfo *ic;
- java_handle_objectarray_t *oa;
- u4 i;
-
- if (!(c->state & CLASS_LINKED))
- if (!link_class(c))
- return NULL;
-
- oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
-
- if (oa == NULL)
- return NULL;
-
- for (i = 0; i < c->interfacescount; i++) {
- ic = c->interfaces[i];
-
- LLNI_array_direct(oa, i) = (java_object_t *) ic;
- }
-
- return oa;
-}
-
-
-/* class_get_annotations *******************************************************
-
- Get the unparsed declared annotations in a byte array
- of the given class.
-
- IN:
- c........the class of which the annotations should be returned
-
- RETURN VALUE:
- The unparsed declared annotations in a byte array
- (or NULL if there aren't any).
-
-*******************************************************************************/
-
-java_handle_bytearray_t *class_get_annotations(classinfo *c)
-{
-#if defined(ENABLE_ANNOTATIONS)
- java_handle_t *annotations; /* unparsed annotations */
-
- LLNI_classinfo_field_get(c, annotations, annotations);
-
- return (java_handle_bytearray_t*)annotations;
-#else
- return NULL;
-#endif
-}
-
-
-/* class_get_modifiers *********************************************************
-
- Get the modifier flags of the given class.
-
- IN:
- c....the class of which the modifier flags should be returned
- ignoreInnerClassesAttrib
- RETURN VALUE:
- modifier flags
-
-*******************************************************************************/
-
-int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
-{
- classref_or_classinfo inner;
- classref_or_classinfo outer;
- utf *innername;
- int i;
-
- if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
- /* search for passed class as inner class */
-
- for (i = 0; i < c->innerclasscount; i++) {
- inner = c->innerclass[i].inner_class;
- outer = c->innerclass[i].outer_class;
-
- /* Check if inner is a classref or a real class and get
- the name of the structure */
-
- innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
-
- /* innerclass is this class */
-
- if (innername == c->name) {
- /* has the class actually an outer class? */
-
- if (outer.any)
- /* return flags got from the outer class file */
- return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
- else
- return c->flags & ACC_CLASS_REFLECT_MASK;
- }
- }
- }
-
- /* passed class is no inner class or it was not requested */
-
- return c->flags & ACC_CLASS_REFLECT_MASK;
-}
-
-
-/* class_get_signature *********************************************************
-
- Return the signature of the given class. For array and primitive
- classes return NULL.
-
-*******************************************************************************/
-
-#if defined(ENABLE_JAVASE)
-utf *class_get_signature(classinfo *c)
-{
- /* For array and primitive classes return NULL. */
-
- if (class_is_array(c) || class_is_primitive(c))
- return NULL;
-
- return c->signature;
-}
-#endif
-
-
-/* class_printflags ************************************************************
-
- Prints flags of a class.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_printflags(classinfo *c)
-{
- if (c == NULL) {
- printf("NULL");
- return;
- }
-
- if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
- if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
- if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
- if (c->flags & ACC_STATIC) printf(" STATIC");
- if (c->flags & ACC_FINAL) printf(" FINAL");
- if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
- if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
- if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
- if (c->flags & ACC_NATIVE) printf(" NATIVE");
- if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
- if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
-}
-#endif
-
-
-/* class_print *****************************************************************
-
- Prints classname plus flags.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_print(classinfo *c)
-{
- if (c == NULL) {
- printf("NULL");
- return;
- }
-
- utf_display_printable_ascii(c->name);
- class_printflags(c);
-}
-#endif
-
-
-/* class_classref_print ********************************************************
-
- Prints classname plus referer class.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_classref_print(constant_classref *cr)
-{
- if (cr == NULL) {
- printf("NULL");
- return;
- }
-
- utf_display_printable_ascii(cr->name);
- printf("(ref.by ");
- if (cr->referer)
- class_print(cr->referer);
- else
- printf("NULL");
- printf(")");
-}
-#endif
-
-
-/* class_println ***************************************************************
-
- Prints classname plus flags and new line.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_println(classinfo *c)
-{
- class_print(c);
- printf("\n");
-}
-#endif
-
-
-/* class_classref_println ******************************************************
-
- Prints classname plus referer class and new line.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_classref_println(constant_classref *cr)
-{
- class_classref_print(cr);
- printf("\n");
-}
-#endif
-
-
-/* class_classref_or_classinfo_print *******************************************
-
- Prints classname plus referer class.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_classref_or_classinfo_print(classref_or_classinfo c)
-{
- if (c.any == NULL) {
- printf("(classref_or_classinfo) NULL");
- return;
- }
- if (IS_CLASSREF(c))
- class_classref_print(c.ref);
- else
- class_print(c.cls);
-}
-#endif
-
-
-/* class_classref_or_classinfo_println *****************************************
-
- Prints classname plus referer class and a newline.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_classref_or_classinfo_println(classref_or_classinfo c)
-{
- class_classref_or_classinfo_print(c);
- printf("\n");
-}
-#endif
-
-
-/* class_showconstantpool ******************************************************
-
- Dump the constant pool of the given class to stdout.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_showconstantpool (classinfo *c)
-{
- u4 i;
- void* e;
-
- printf ("---- dump of constant pool ----\n");
-
- for (i=0; i<c->cpcount; i++) {
- printf ("#%d: ", (int) i);
-
- e = c -> cpinfos [i];
- if (e) {
-
- switch (c -> cptags [i]) {
- case CONSTANT_Class:
- printf ("Classreference -> ");
- utf_display_printable_ascii ( ((constant_classref*)e) -> name );
- break;
- case CONSTANT_Fieldref:
- printf ("Fieldref -> ");
- field_fieldref_print((constant_FMIref *) e);
- break;
- case CONSTANT_Methodref:
- printf ("Methodref -> ");
- method_methodref_print((constant_FMIref *) e);
- break;
- case CONSTANT_InterfaceMethodref:
- printf ("InterfaceMethod -> ");
- method_methodref_print((constant_FMIref *) e);
- break;
- case CONSTANT_String:
- printf ("String -> ");
- utf_display_printable_ascii (e);
- break;
- case CONSTANT_Integer:
- printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
- break;
- case CONSTANT_Float:
- printf ("Float -> %f", ((constant_float*)e) -> value);
- break;
- case CONSTANT_Double:
- printf ("Double -> %f", ((constant_double*)e) -> value);
- break;
- case CONSTANT_Long:
- printf ("Long -> %ld", (long int) ((constant_long*)e) -> value);
- break;
- case CONSTANT_NameAndType:
- {
- constant_nameandtype *cnt = e;
- printf ("NameAndType: ");
- utf_display_printable_ascii (cnt->name);
- printf (" ");
- utf_display_printable_ascii (cnt->descriptor);
- }
- break;
- case CONSTANT_Utf8:
- printf ("Utf8 -> ");
- utf_display_printable_ascii (e);
- break;
- default:
- log_text("Invalid type of ConstantPool-Entry");
- assert(0);
- }
- }
-
- printf ("\n");
- }
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* class_showmethods ***********************************************************
-
- Dump info about the fields and methods of the given class to stdout.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_showmethods (classinfo *c)
-{
- s4 i;
-
- printf("--------- Fields and Methods ----------------\n");
- printf("Flags: ");
- class_printflags(c);
- printf("\n");
-
- printf("This: ");
- utf_display_printable_ascii(c->name);
- printf("\n");
-
- if (c->super) {
- printf("Super: ");
- utf_display_printable_ascii(c->super->name);
- printf ("\n");
- }
-
- printf("Index: %d\n", c->index);
-
- printf("Interfaces:\n");
- for (i = 0; i < c->interfacescount; i++) {
- printf(" ");
- utf_display_printable_ascii(c->interfaces[i]->name);
- printf (" (%d)\n", c->interfaces[i]->index);
- }
-
- printf("Fields:\n");
- for (i = 0; i < c->fieldscount; i++)
- field_println(&(c->fields[i]));
-
- printf("Methods:\n");
- for (i = 0; i < c->methodscount; i++) {
- methodinfo *m = &(c->methods[i]);
-
- if (!(m->flags & ACC_STATIC))
- printf("vftblindex: %d ", m->vftblindex);
-
- method_println(m);
- }
-
- printf ("Virtual function table:\n");
- for (i = 0; i < c->vftbl->vftbllength; i++)
- printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
-}
-#endif /* !defined(NDEBUG) */
-
-
-/*
- * 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/class.cpp - class related functions
+
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+ 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.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "vm/types.h"
+
+#include "arch.h"
+
+#include "mm/memory.h"
+
+#include "native/llni.h"
+
+#include "threads/lock.hpp"
+#include "threads/mutex.hpp"
+
+#include "toolbox/logging.h"
+
+#include "vm/array.hpp"
+#include "vm/jit/builtin.hpp"
+#include "vm/class.hpp"
+#include "vm/classcache.h"
+#include "vm/exceptions.hpp"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/javaobjects.hpp"
+#include "vm/linker.h"
+#include "vm/loader.hpp"
+#include "vm/options.h"
+#include "vm/resolve.hpp"
+
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
+#include "vm/suck.hpp"
+#include "vm/utf8.h"
+
+#include "vm/jit/asmpart.h"
+
+
+/* class_set_packagename *******************************************************
+
+ Derive the package name from the class name and store it in the
+ struct.
+
+ An internal package name consists of the package name plus the
+ trailing '/', e.g. "java/lang/".
+
+ For classes in the unnamed package, the package name is set to
+ NULL.
+
+*******************************************************************************/
+
+void class_set_packagename(classinfo *c)
+{
+ char *p;
+ char *start;
+
+ p = UTF_END(c->name) - 1;
+ start = c->name->text;
+
+ if (c->name->text[0] == '[') {
+ /* Set packagename of arrays to the element's package. */
+
+ for (; *start == '['; start++);
+
+ /* Skip the 'L' in arrays of references. */
+
+ if (*start == 'L')
+ start++;
+ }
+
+ /* Search for last '/'. */
+
+ for (; (p > start) && (*p != '/'); --p);
+
+ /* If we found a '/' we set the package name plus the trailing
+ '/'. Otherwise we set the packagename to NULL. */
+
+ if (p > start)
+ c->packagename = utf_new(start, p - start + 1);
+ else
+ c->packagename = NULL;
+}
+
+
+/* class_create_classinfo ******************************************************
+
+ Create a new classinfo struct. The class name is set to the given utf *,
+ most other fields are initialized to zero.
+
+ Note: classname may be NULL. In this case a not-yet-named classinfo is
+ created. The name must be filled in later and class_set_packagename
+ must be called after that.
+
+*******************************************************************************/
+
+classinfo *class_create_classinfo(utf *classname)
+{
+ classinfo *c;
+
+#if defined(ENABLE_STATISTICS)
+ if (opt_stat)
+ size_classinfo += sizeof(classinfo);
+#endif
+
+ /* we use a safe name for temporarily unnamed classes */
+
+ if (classname == NULL)
+ classname = utf_not_named_yet;
+
+#if !defined(NDEBUG)
+ if (initverbose)
+ log_message_utf("Creating class: ", classname);
+#endif
+
+#if !defined(ENABLE_GC_BOEHM)
+ c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
+ /*c = NEW(classinfo);
+ MZERO(c, classinfo, 1);*/
+#else
+ c = GCNEW_UNCOLLECTABLE(classinfo, 1);
+ /* GCNEW_UNCOLLECTABLE clears the allocated memory */
+#endif
+
+ c->name = classname;
+
+ /* Set the header.vftbl of all loaded classes to the one of
+ java.lang.Class, so Java code can use a class as object. */
+
+ if (class_java_lang_Class != NULL)
+ if (class_java_lang_Class->vftbl != NULL)
+ c->object.header.vftbl = class_java_lang_Class->vftbl;
+
+#if defined(ENABLE_JAVASE)
+ /* check if the class is a reference class and flag it */
+
+ if (classname == utf_java_lang_ref_SoftReference) {
+ c->flags |= ACC_CLASS_REFERENCE_SOFT;
+ }
+ else if (classname == utf_java_lang_ref_WeakReference) {
+ c->flags |= ACC_CLASS_REFERENCE_WEAK;
+ }
+ else if (classname == utf_java_lang_ref_PhantomReference) {
+ c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
+ }
+#endif
+
+ if (classname != utf_not_named_yet)
+ class_set_packagename(c);
+
+ c->object.header.lockword.init();
+
+ return c;
+}
+
+
+/* class_postset_header_vftbl **************************************************
+
+ Set the header.vftbl of all classes created before java.lang.Class
+ was linked. This is necessary that Java code can use a class as
+ object.
+
+*******************************************************************************/
+
+void class_postset_header_vftbl(void)
+{
+ classinfo *c;
+ u4 slot;
+ classcache_name_entry *nmen;
+ classcache_class_entry *clsen;
+
+ assert(class_java_lang_Class);
+
+ for (slot = 0; slot < hashtable_classcache.size; slot++) {
+ nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
+
+ for (; nmen; nmen = nmen->hashlink) {
+ /* iterate over all class entries */
+
+ for (clsen = nmen->classes; clsen; clsen = clsen->next) {
+ c = clsen->classobj;
+
+ /* now set the the vftbl */
+
+ if (c->object.header.vftbl == NULL)
+ c->object.header.vftbl = class_java_lang_Class->vftbl;
+ }
+ }
+ }
+}
+
+/* class_define ****************************************************************
+
+ Calls the loader and defines a class in the VM.
+
+*******************************************************************************/
+
+classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
+{
+ classinfo *c;
+ classinfo *r;
+ classbuffer *cb;
+
+ if (name != NULL) {
+ /* check if this class has already been defined */
+
+ c = classcache_lookup_defined_or_initiated(cl, name);
+
+ if (c != NULL) {
+ exceptions_throw_linkageerror("duplicate class definition: ", c);
+ return NULL;
+ }
+ }
+
+ /* create a new classinfo struct */
+
+ c = class_create_classinfo(name);
+
+#if defined(ENABLE_STATISTICS)
+ /* measure time */
+
+ if (opt_getloadingtime)
+ loadingtime_start();
+#endif
+
+ /* build a classbuffer with the given data */
+
+ cb = NEW(classbuffer);
+
+ cb->clazz = c;
+ cb->size = length;
+ cb->data = data;
+ cb->pos = cb->data;
+
+ /* preset the defining classloader */
+
+ c->classloader = cl;
+
+ /* load the class from this buffer */
+
+ r = load_class_from_classbuffer(cb);
+
+ /* free memory */
+
+ FREE(cb, classbuffer);
+
+#if defined(ENABLE_STATISTICS)
+ /* measure time */
+
+ if (opt_getloadingtime)
+ loadingtime_stop();
+#endif
+
+ if (r == NULL) {
+ /* If return value is NULL, we had a problem and the class is
+ not loaded. Now free the allocated memory, otherwise we
+ could run into a DOS. */
+
+ class_free(c);
+
+ return NULL;
+ }
+
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+ /* Store the protection domain. */
+
+ c->protectiondomain = pd;
+# endif
+#endif
+
+ /* Store the newly defined class in the class cache. This call
+ also checks whether a class of the same name has already been
+ defined by the same defining loader, and if so, replaces the
+ newly created class by the one defined earlier. */
+
+ /* Important: The classinfo given to classcache_store must be
+ fully prepared because another thread may return
+ this pointer after the lookup at to top of this
+ function directly after the class cache lock has
+ been released. */
+
+ c = classcache_store(cl, c, true);
+
+ return c;
+}
+
+
+/* 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->clazz;
+
+ /* 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 = (utf*) 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;
+ }
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+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->clazz;
+
+ /* 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 = (constant_classref*) innerclass_getconstant(c, class_index, CONSTANT_Class);
+
+ /* get method index */
+
+ method_index = suck_u2(cb);
+ cn = (constant_nameandtype*) innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
+
+ /* store info in classinfo */
+
+ c->enclosingclass.any = cr.any;
+ c->enclosingmethod = cn;
+
+ return true;
+}
+#endif /* defined(ENABLE_JAVASE) */
+
+
+/* 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;
+ uint16_t attributes_count;
+ uint16_t attribute_name_index;
+ utf *attribute_name;
+ innerclassinfo *info;
+ classref_or_classinfo inner;
+ classref_or_classinfo outer;
+ utf *name;
+ uint16_t flags;
+ int i, j;
+
+ c = cb->clazz;
+
+ /* 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 =
+ (utf*) 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. */
+
+ info = c->innerclass + j;
+
+ inner.ref = (constant_classref*) innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
+ outer.ref = (constant_classref*) innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
+ name = (utf*) innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
+ flags = suck_u2(cb);
+
+ /* If the current inner-class is the currently loaded
+ class check for some special flags. */
+
+ if (inner.ref->name == c->name) {
+ /* If an inner-class is not a member, its
+ outer-class is NULL. */
+
+ if (outer.ref != NULL) {
+ c->flags |= ACC_CLASS_MEMBER;
+
+ /* A member class doesn't have an
+ EnclosingMethod attribute, so set the
+ enclosing-class to be the same as the
+ declaring-class. */
+
+ c->declaringclass = outer;
+ c->enclosingclass = outer;
+ }
+
+ /* If an inner-class is anonymous, its name is
+ NULL. */
+
+ if (name == NULL)
+ c->flags |= ACC_CLASS_ANONYMOUS;
+ }
+
+ info->inner_class = inner;
+ info->outer_class = outer;
+ info->name = name;
+ info->flags = flags;
+ }
+ }
+ 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;
+ }
+#endif
+
+#if defined(ENABLE_ANNOTATIONS)
+ else if (attribute_name == utf_RuntimeVisibleAnnotations) {
+ /* RuntimeVisibleAnnotations */
+ if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
+ return false;
+ }
+ else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
+ /* RuntimeInvisibleAnnotations */
+ if (!annotation_load_class_attribute_runtimeinvisibleannotations(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.
+
+*******************************************************************************/
+
+static void class_freecpool(classinfo *c)
+{
+ u4 idx;
+ u4 tag;
+ void* info;
+
+ if (c->cptags && c->cpinfos) {
+ for (idx = 0; idx < c->cpcount; idx++) {
+ tag = c->cptags[idx];
+ info = c->cpinfos[idx];
+
+ if (info != NULL) {
+ switch (tag) {
+ case CONSTANT_Fieldref:
+ case CONSTANT_Methodref:
+ case CONSTANT_InterfaceMethodref:
+ FREE(info, constant_FMIref);
+ break;
+ case CONSTANT_Integer:
+ FREE(info, constant_integer);
+ break;
+ case CONSTANT_Float:
+ FREE(info, constant_float);
+ break;
+ case CONSTANT_Long:
+ FREE(info, constant_long);
+ break;
+ case CONSTANT_Double:
+ FREE(info, constant_double);
+ break;
+ case CONSTANT_NameAndType:
+ FREE(info, constant_nameandtype);
+ break;
+ }
+ }
+ }
+ }
+
+ if (c->cptags)
+ MFREE(c->cptags, u1, c->cpcount);
+
+ if (c->cpinfos)
+ MFREE(c->cpinfos, void*, c->cpcount);
+}
+
+
+/* class_getconstant ***********************************************************
+
+ Retrieves the value at position 'pos' of the constantpool of a
+ class. If the type of the value is other than 'ctype', an error is
+ thrown.
+
+*******************************************************************************/
+
+void* 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)) {
+ exceptions_throw_classformaterror(c, "Illegal constant pool index");
+ return NULL;
+ }
+
+ return c->cpinfos[pos];
+}
+
+
+/* innerclass_getconstant ******************************************************
+
+ Like class_getconstant, but if cptags is ZERO, null is returned.
+
+*******************************************************************************/
+
+void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
+{
+ /* invalid position in constantpool */
+
+ if (pos >= c->cpcount) {
+ exceptions_throw_classformaterror(c, "Illegal constant pool index");
+ return NULL;
+ }
+
+ /* constantpool entry of type 0 */
+
+ if (c->cptags[pos] == 0)
+ return NULL;
+
+ /* check type of constantpool entry */
+
+ if (c->cptags[pos] != ctype) {
+ exceptions_throw_classformaterror(c, "Illegal constant pool index");
+ return NULL;
+ }
+
+ return c->cpinfos[pos];
+}
+
+
+/* class_free ******************************************************************
+
+ Frees all resources used by the class.
+
+*******************************************************************************/
+
+void class_free(classinfo *c)
+{
+ s4 i;
+ vftbl_t *v;
+
+ class_freecpool(c);
+
+ if (c->interfaces != NULL)
+ MFREE(c->interfaces, classinfo*, c->interfacescount);
+
+ if (c->fields) {
+ for (i = 0; i < c->fieldscount; i++)
+ field_free(&(c->fields[i]));
+ MFREE(c->fields, fieldinfo, c->fieldscount);
+ }
+
+ if (c->methods) {
+ for (i = 0; i < c->methodscount; i++)
+ method_free(&(c->methods[i]));
+ MFREE(c->methods, methodinfo, c->methodscount);
+ }
+
+ if ((v = c->vftbl) != NULL) {
+ if (v->arraydesc)
+ mem_free(v->arraydesc,sizeof(arraydescriptor));
+
+ for (i = 0; i < v->interfacetablelength; i++) {
+ MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
+ }
+ MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
+
+ i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
+ sizeof(methodptr*) * (v->interfacetablelength -
+ (v->interfacetablelength > 0));
+ v = (vftbl_t*) (((methodptr*) v) -
+ (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
+ mem_free(v, i);
+ }
+
+ if (c->innerclass)
+ MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
+
+ /* if (c->classvftbl)
+ mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
+
+/* GCFREE(c); */
+}
+
+
+/* get_array_class *************************************************************
+
+ Returns the array class with the given name for the given
+ classloader, or NULL if an exception occurred.
+
+ Note: This function does eager loading.
+
+*******************************************************************************/
+
+static classinfo *get_array_class(utf *name,classloader_t *initloader,
+ classloader_t *defloader,bool link)
+{
+ classinfo *c;
+
+ /* lookup this class in the classcache */
+ c = classcache_lookup(initloader,name);
+ if (!c)
+ c = classcache_lookup_defined(defloader,name);
+
+ if (!c) {
+ /* we have to create it */
+ c = class_create_classinfo(name);
+ c = load_newly_created_array(c,initloader);
+ if (c == NULL)
+ return NULL;
+ }
+
+ assert(c);
+ assert(c->state & CLASS_LOADED);
+ assert(c->classloader == defloader);
+
+ if (link && !(c->state & CLASS_LINKED))
+ if (!link_class(c))
+ return NULL;
+
+ assert(!link || (c->state & CLASS_LINKED));
+
+ return c;
+}
+
+
+/* class_array_of **************************************************************
+
+ Returns an array class with the given component class. The array
+ class is dynamically created if neccessary.
+
+*******************************************************************************/
+
+classinfo *class_array_of(classinfo *component, bool link)
+{
+ classloader_t *cl;
+ s4 namelen;
+ char *namebuf;
+ utf *u;
+ classinfo *c;
+
+ cl = component->classloader;
+
+ /* Assemble the array class name */
+ namelen = component->name->blength;
+
+ if (component->name->text[0] == '[') {
+ /* the component is itself an array */
+ namebuf = MNEW(char, namelen + 1);
+ namebuf[0] = '[';
+ MCOPY(namebuf + 1, component->name->text, char, namelen);
+ namelen++;
+ }
+ else {
+ /* the component is a non-array class */
+ namebuf = MNEW(char, namelen + 3);
+ namebuf[0] = '[';
+ namebuf[1] = 'L';
+ MCOPY(namebuf + 2, component->name->text, char, namelen);
+ namebuf[2 + namelen] = ';';
+ namelen += 3;
+ }
+
+ u = utf_new(namebuf, namelen);
+
+ MFREE(namebuf, char, namelen);
+
+ c = get_array_class(u, cl, cl, link);
+
+ return c;
+}
+
+
+/* class_multiarray_of *********************************************************
+
+ Returns an array class with the given dimension and element class.
+ The array class is dynamically created if neccessary.
+
+*******************************************************************************/
+
+classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
+{
+ s4 namelen;
+ char *namebuf;
+ classinfo *c;
+
+ if (dim < 1) {
+ log_text("Invalid array dimension requested");
+ assert(0);
+ }
+
+ /* Assemble the array class name */
+ namelen = element->name->blength;
+
+ if (element->name->text[0] == '[') {
+ /* the element is itself an array */
+ namebuf = MNEW(char, namelen + dim);
+ memcpy(namebuf + dim, element->name->text, namelen);
+ namelen += dim;
+ }
+ else {
+ /* the element is a non-array class */
+ namebuf = MNEW(char, namelen + 2 + dim);
+ namebuf[dim] = 'L';
+ memcpy(namebuf + dim + 1, element->name->text, namelen);
+ namelen += (2 + dim);
+ namebuf[namelen - 1] = ';';
+ }
+ memset(namebuf, '[', dim);
+
+ utf* u = utf_new(namebuf, namelen);
+
+ MFREE(namebuf, char, namelen);
+
+ c = get_array_class(u,
+ element->classloader,
+ element->classloader,
+ link);
+
+ return c;
+}
+
+
+/* class_lookup_classref *******************************************************
+
+ Looks up the constant_classref for a given classname in the classref
+ tables of a class.
+
+ IN:
+ cls..............the class containing the reference
+ name.............the name of the class refered to
+
+ RETURN VALUE:
+ a pointer to a constant_classref, or
+ NULL if the reference was not found
+
+*******************************************************************************/
+
+constant_classref *class_lookup_classref(classinfo *cls, utf *name)
+{
+ constant_classref *ref;
+ extra_classref *xref;
+ int count;
+
+ assert(cls);
+ assert(name);
+ assert(!cls->classrefcount || cls->classrefs);
+
+ /* first search the main classref table */
+ count = cls->classrefcount;
+ ref = cls->classrefs;
+ for (; count; --count, ++ref)
+ if (ref->name == name)
+ return ref;
+
+ /* next try the list of extra classrefs */
+ for (xref = cls->extclassrefs; xref; xref = xref->next) {
+ if (xref->classref.name == name)
+ return &(xref->classref);
+ }
+
+ /* not found */
+ return NULL;
+}
+
+
+/* class_get_classref **********************************************************
+
+ Returns the constant_classref for a given classname.
+
+ IN:
+ cls..............the class containing the reference
+ name.............the name of the class refered to
+
+ RETURN VALUE:
+ a pointer to a constant_classref (never NULL)
+
+ NOTE:
+ The given name is not checked for validity!
+
+*******************************************************************************/
+
+constant_classref *class_get_classref(classinfo *cls, utf *name)
+{
+ constant_classref *ref;
+ extra_classref *xref;
+
+ assert(cls);
+ assert(name);
+
+ ref = class_lookup_classref(cls,name);
+ if (ref)
+ return ref;
+
+ xref = NEW(extra_classref);
+ CLASSREF_INIT(xref->classref,cls,name);
+
+ xref->next = cls->extclassrefs;
+ cls->extclassrefs = xref;
+
+ return &(xref->classref);
+}
+
+
+/* class_get_self_classref *****************************************************
+
+ Returns the constant_classref to the class itself.
+
+ IN:
+ cls..............the class containing the reference
+
+ RETURN VALUE:
+ a pointer to a constant_classref (never NULL)
+
+*******************************************************************************/
+
+constant_classref *class_get_self_classref(classinfo *cls)
+{
+ /* XXX this should be done in a faster way. Maybe always make */
+ /* the classref of index 0 a self reference. */
+ return class_get_classref(cls,cls->name);
+}
+
+/* class_get_classref_multiarray_of ********************************************
+
+ Returns an array type reference with the given dimension and element class
+ reference.
+
+ IN:
+ dim..............the requested dimension
+ dim must be in [1;255]. This is NOT checked!
+ ref..............the component class reference
+
+ RETURN VALUE:
+ a pointer to the class reference for the array type
+
+ NOTE:
+ The referer of `ref` is used as the referer for the new classref.
+
+*******************************************************************************/
+
+constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
+{
+ s4 namelen;
+ char *namebuf;
+ constant_classref *cr;
+
+ assert(ref);
+ assert(dim >= 1 && dim <= 255);
+
+ /* Assemble the array class name */
+ namelen = ref->name->blength;
+
+ if (ref->name->text[0] == '[') {
+ /* the element is itself an array */
+ namebuf = MNEW(char, namelen + dim);
+ memcpy(namebuf + dim, ref->name->text, namelen);
+ namelen += dim;
+ }
+ else {
+ /* the element is a non-array class */
+ namebuf = MNEW(char, namelen + 2 + dim);
+ namebuf[dim] = 'L';
+ memcpy(namebuf + dim + 1, ref->name->text, namelen);
+ namelen += (2 + dim);
+ namebuf[namelen - 1] = ';';
+ }
+ memset(namebuf, '[', dim);
+
+ utf* u = utf_new(namebuf, namelen);
+
+ MFREE(namebuf, char, namelen);
+
+ cr = class_get_classref(ref->referer, u);
+
+ return cr;
+}
+
+
+/* class_get_classref_component_of *********************************************
+
+ Returns the component classref of a given array type reference
+
+ IN:
+ ref..............the array type reference
+
+ RETURN VALUE:
+ a reference to the component class, or
+ NULL if `ref` is not an object array type reference
+
+ NOTE:
+ The referer of `ref` is used as the referer for the new classref.
+
+*******************************************************************************/
+
+constant_classref *class_get_classref_component_of(constant_classref *ref)
+{
+ s4 namelen;
+ char *name;
+
+ assert(ref);
+
+ name = ref->name->text;
+ if (*name++ != '[')
+ return NULL;
+
+ namelen = ref->name->blength - 1;
+ if (*name == 'L') {
+ name++;
+ namelen -= 2;
+ }
+ else if (*name != '[') {
+ return NULL;
+ }
+
+ return class_get_classref(ref->referer, utf_new(name, namelen));
+}
+
+
+/* class_findmethod ************************************************************
+
+ Searches a 'classinfo' structure for a method having the given name
+ and descriptor. If descriptor is NULL, it is ignored.
+
+*******************************************************************************/
+
+methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
+{
+ methodinfo *m;
+ s4 i;
+
+ for (i = 0; i < c->methodscount; i++) {
+ m = &(c->methods[i]);
+
+ if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
+ return m;
+ }
+
+ return NULL;
+}
+
+
+/* class_resolvemethod *********************************************************
+
+ Searches a class and it's super classes for a method.
+
+ Superinterfaces are *not* searched.
+
+*******************************************************************************/
+
+methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
+{
+ methodinfo *m;
+
+ while (c) {
+ m = class_findmethod(c, name, desc);
+
+ if (m)
+ return m;
+
+ /* JVM Specification bug:
+
+ It is important NOT to resolve special <init> and <clinit>
+ methods to super classes or interfaces; yet, this is not
+ explicited in the specification. Section 5.4.3.3 should be
+ updated appropriately. */
+
+ if (name == utf_init || name == utf_clinit)
+ return NULL;
+
+ c = c->super;
+ }
+
+ return NULL;
+}
+
+
+/* class_resolveinterfacemethod_intern *****************************************
+
+ Internally used helper function. Do not use this directly.
+
+*******************************************************************************/
+
+static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
+ utf *name, utf *desc)
+{
+ methodinfo *m;
+ s4 i;
+
+ /* try to find the method in the class */
+
+ m = class_findmethod(c, name, desc);
+
+ if (m != NULL)
+ return m;
+
+ /* No method found? Try the super interfaces. */
+
+ for (i = 0; i < c->interfacescount; i++) {
+ m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
+
+ if (m != NULL)
+ return m;
+ }
+
+ /* no method found */
+
+ return NULL;
+}
+
+
+/* class_resolveclassmethod ****************************************************
+
+ Resolves a reference from REFERER to a method with NAME and DESC in
+ class C.
+
+ If the method cannot be resolved the return value is NULL. If
+ EXCEPT is true *exceptionptr is set, too.
+
+*******************************************************************************/
+
+methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
+ classinfo *referer, bool throwexception)
+{
+ classinfo *cls;
+ methodinfo *m;
+ s4 i;
+
+/* if (c->flags & ACC_INTERFACE) { */
+/* if (throwexception) */
+/* *exceptionptr = */
+/* new_exception(string_java_lang_IncompatibleClassChangeError); */
+/* return NULL; */
+/* } */
+
+ /* try class c and its superclasses */
+
+ cls = c;
+
+ m = class_resolvemethod(cls, name, desc);
+
+ if (m != NULL)
+ goto found;
+
+ /* Try the super interfaces. */
+
+ for (i = 0; i < c->interfacescount; i++) {
+ m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
+
+ if (m != NULL)
+ goto found;
+ }
+
+ if (throwexception)
+ exceptions_throw_nosuchmethoderror(c, name, desc);
+
+ return NULL;
+
+ found:
+ if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
+ if (throwexception)
+ exceptions_throw_abstractmethoderror();
+
+ return NULL;
+ }
+
+ /* XXX check access rights */
+
+ return m;
+}
+
+
+/* class_resolveinterfacemethod ************************************************
+
+ Resolves a reference from REFERER to a method with NAME and DESC in
+ interface C.
+
+ If the method cannot be resolved the return value is NULL. If
+ EXCEPT is true *exceptionptr is set, too.
+
+*******************************************************************************/
+
+methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
+ classinfo *referer, bool throwexception)
+{
+ methodinfo *mi;
+
+ if (!(c->flags & ACC_INTERFACE)) {
+ if (throwexception)
+ exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
+
+ return NULL;
+ }
+
+ mi = class_resolveinterfacemethod_intern(c, name, desc);
+
+ if (mi != NULL)
+ return mi;
+
+ /* try class java.lang.Object */
+
+ mi = class_findmethod(class_java_lang_Object, name, desc);
+
+ if (mi != NULL)
+ return mi;
+
+ if (throwexception)
+ exceptions_throw_nosuchmethoderror(c, name, desc);
+
+ return NULL;
+}
+
+
+/* class_findfield *************************************************************
+
+ Searches for field with specified name and type in a classinfo
+ structure. If no such field is found NULL is returned.
+
+*******************************************************************************/
+
+fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
+{
+ s4 i;
+
+ for (i = 0; i < c->fieldscount; i++)
+ if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
+ return &(c->fields[i]);
+
+ if (c->super != NULL)
+ return class_findfield(c->super, name, desc);
+
+ return NULL;
+}
+
+
+/* class_findfield_approx ******************************************************
+
+ Searches in 'classinfo'-structure for a field with the specified
+ name.
+
+*******************************************************************************/
+
+fieldinfo *class_findfield_by_name(classinfo* c, utf* name)
+{
+ for (int32_t i = 0; i < c->fieldscount; i++) {
+ fieldinfo* f = &(c->fields[i]);
+
+ if (f->name == name)
+ return f;
+ }
+
+ // Field not found.
+ exceptions_throw_nosuchfielderror(c, name);
+ return NULL;
+}
+
+
+/****************** Function: class_resolvefield_int ***************************
+
+ This is an internally used helper function. Do not use this directly.
+
+ Tries to resolve a field having the given name and type.
+ If the field cannot be resolved, NULL is returned.
+
+*******************************************************************************/
+
+static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
+{
+ fieldinfo *fi;
+ s4 i;
+
+ /* search for field in class c */
+
+ for (i = 0; i < c->fieldscount; i++) {
+ if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
+ return &(c->fields[i]);
+ }
+ }
+
+ /* Try super interfaces recursively. */
+
+ for (i = 0; i < c->interfacescount; i++) {
+ fi = class_resolvefield_int(c->interfaces[i], name, desc);
+
+ if (fi != NULL)
+ return fi;
+ }
+
+ /* Try super class. */
+
+ if (c->super != NULL)
+ return class_resolvefield_int(c->super, name, desc);
+
+ /* not found */
+
+ return NULL;
+}
+
+
+/********************* Function: class_resolvefield ***************************
+
+ Resolves a reference from REFERER to a field with NAME and DESC in class C.
+
+ If the field cannot be resolved, an exception is thrown and the
+ return value is NULL.
+
+*******************************************************************************/
+
+fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer)
+{
+ fieldinfo *fi;
+
+ fi = class_resolvefield_int(c, name, desc);
+
+ if (!fi) {
+ exceptions_throw_nosuchfielderror(c, name);
+ return NULL;
+ }
+
+ /* XXX check access rights */
+
+ return fi;
+}
+
+
+/* class_issubclass ************************************************************
+
+ Checks if sub is a descendant of super.
+
+*******************************************************************************/
+
+bool class_issubclass(classinfo *sub, classinfo *super)
+{
+ classinfo *c;
+
+ c = sub;
+
+ for (;;) {
+ /* We reached java/lang/Object and did not find the requested
+ super class. */
+
+ if (c == NULL)
+ return false;
+
+ /* We found the requested super class. */
+
+ if (c == super)
+ return true;
+
+ c = c->super;
+ }
+}
+
+
+/* class_isanysubclass *********************************************************
+
+ Checks a subclass relation between two classes. Implemented
+ interfaces are interpreted as super classes.
+
+ Return value: 1 ... sub is subclass of super
+ 0 ... otherwise
+
+*******************************************************************************/
+
+bool class_isanysubclass(classinfo *sub, classinfo *super)
+{
+ uint32_t diffval;
+ bool result;
+
+ /* This is the trivial case. */
+
+ if (sub == super)
+ return true;
+
+ /* Primitive classes are only subclasses of themselves. */
+
+ if (class_is_primitive(sub) || class_is_primitive(super))
+ return false;
+
+ /* Check for interfaces. */
+
+ if (super->flags & ACC_INTERFACE) {
+ result = (sub->vftbl->interfacetablelength > super->index) &&
+ (sub->vftbl->interfacetable[-super->index] != NULL);
+ }
+ else {
+ /* java.lang.Object is the only super class of any
+ interface. */
+
+ if (sub->flags & ACC_INTERFACE)
+ return (super == class_java_lang_Object);
+
+ linker_classrenumber_mutex->lock();
+
+ diffval = sub->vftbl->baseval - super->vftbl->baseval;
+ result = diffval <= (uint32_t) super->vftbl->diffval;
+
+ linker_classrenumber_mutex->unlock();
+ }
+
+ return result;
+}
+
+
+/* class_is_assignable_from ****************************************************
+
+ Return whether an instance of the "from" class parameter would be
+ an instance of this class "to" as well.
+
+ ARGUMENTS:
+ to ..... class
+ from ... class
+
+ RETURN:
+ true .... is assignable
+ false ... is not assignable
+
+*******************************************************************************/
+
+bool class_is_assignable_from(classinfo *to, classinfo *from)
+{
+ if (!(to->state & CLASS_LINKED))
+ if (!link_class(to))
+ return false;
+
+ if (!(from->state & CLASS_LINKED))
+ if (!link_class(from))
+ return false;
+
+ return class_isanysubclass(from, to);
+}
+
+
+/* class_is_instance ***********************************************************
+
+ Return if the given Java object is an instance of the given class.
+
+ ARGUMENTS:
+ c ... class
+ h ... Java object
+
+ RETURN:
+ true .... is instance
+ false ... is not instance
+
+*******************************************************************************/
+
+bool class_is_instance(classinfo *c, java_handle_t *h)
+{
+ if (!(c->state & CLASS_LINKED))
+ if (!link_class(c))
+ return false;
+
+ return builtin_instanceof(h, c);
+}
+
+
+/* class_get_componenttype *****************************************************
+
+ Return the component class of the given class. If the given class
+ is not an array, return NULL.
+
+*******************************************************************************/
+
+classinfo *class_get_componenttype(classinfo *c)
+{
+ classinfo *component;
+ arraydescriptor *ad;
+
+ /* XXX maybe we could find a way to do this without linking. */
+ /* This way should be safe and easy, however. */
+
+ if (!(c->state & CLASS_LINKED))
+ if (!link_class(c))
+ return NULL;
+
+ ad = c->vftbl->arraydesc;
+
+ if (ad == NULL)
+ return NULL;
+
+ if (ad->arraytype == ARRAYTYPE_OBJECT)
+ component = ad->componentvftbl->clazz;
+ else
+ component = Primitive::get_class_by_type(ad->arraytype);
+
+ return component;
+}
+
+
+/* class_get_declaredclasses ***************************************************
+
+ Return an array of declared classes of the given class.
+
+*******************************************************************************/
+
+java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
+{
+ classref_or_classinfo inner;
+ classref_or_classinfo outer;
+ utf *outername;
+ int declaredclasscount; /* number of declared classes */
+ int pos; /* current declared class */
+ java_handle_objectarray_t *oa; /* array of declared classes */
+ int i;
+ classinfo *ic;
+
+ declaredclasscount = 0;
+
+ if (!class_is_primitive(c) && !class_is_array(c)) {
+ /* Determine number of declared classes. */
+
+ for (i = 0; i < c->innerclasscount; i++) {
+ /* Get outer-class. If the inner-class is not a member
+ class, the outer-class is NULL. */
+
+ outer = c->innerclass[i].outer_class;
+
+ if (outer.any == NULL)
+ continue;
+
+ /* Check if outer-class is a classref or a real class and
+ get the class name from the structure. */
+
+ outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
+
+ /* Outer class is this class. */
+
+ if ((outername == c->name) &&
+ ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
+ declaredclasscount++;
+ }
+ }
+
+ /* Allocate Class[] and check for OOM. */
+
+ oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
+
+ if (oa == NULL)
+ return NULL;
+
+ for (i = 0, pos = 0; i < c->innerclasscount; i++) {
+ inner = c->innerclass[i].inner_class;
+ outer = c->innerclass[i].outer_class;
+
+ /* Get outer-class. If the inner-class is not a member class,
+ the outer-class is NULL. */
+
+ if (outer.any == NULL)
+ continue;
+
+ /* Check if outer_class is a classref or a real class and get
+ the class name from the structure. */
+
+ outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
+
+ /* Outer class is this class. */
+
+ if ((outername == c->name) &&
+ ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
+
+ ic = resolve_classref_or_classinfo_eager(inner, false);
+
+ if (ic == NULL)
+ return NULL;
+
+ if (!(ic->state & CLASS_LINKED))
+ if (!link_class(ic))
+ return NULL;
+
+ LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
+ }
+ }
+
+ return oa;
+}
+
+
+/**
+ * Return an array of declared constructors of the given class.
+ *
+ * @param c class to get the constructors of
+ * @param publicOnly show only public fields
+ *
+ * @return array of java.lang.reflect.Constructor
+ */
+#if defined(ENABLE_JAVASE)
+java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
+{
+ methodinfo* m;
+ java_handle_objectarray_t* oa;
+ int count;
+ int index;
+ int i;
+
+ /* Determine number of constructors. */
+
+ count = 0;
+
+ for (i = 0; i < c->methodscount; i++) {
+ m = &(c->methods[i]);
+
+ if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
+ (m->name == utf_init))
+ count++;
+ }
+
+ /* Create array of constructors. */
+
+ oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
+
+ if (oa == NULL)
+ return NULL;
+
+ /* Get the constructors and store them in the array. */
+
+ for (i = 0, index = 0; i < c->methodscount; i++) {
+ m = &(c->methods[i]);
+
+ if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
+ (m->name == utf_init)) {
+ // Create a java.lang.reflect.Constructor object.
+
+ java_lang_reflect_Constructor rc(m);
+
+ /* Store object into array. */
+
+ array_objectarray_element_set(oa, index, rc.get_handle());
+ index++;
+ }
+ }
+
+ return oa;
+}
+#endif
+
+
+/* class_get_declaredfields ****************************************************
+
+ Return an array of declared fields of the given class.
+
+ ARGUMENTS:
+ c ............ class to get the fields of
+ publicOnly ... show only public fields
+
+ RETURN:
+ array of java.lang.reflect.Field
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
+{
+ java_handle_objectarray_t *oa;
+ fieldinfo *f;
+ int count;
+ int index;
+ int i;
+
+ /* Determine number of fields. */
+
+ count = 0;
+
+ for (i = 0; i < c->fieldscount; i++)
+ if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
+ count++;
+
+ /* Create array of fields. */
+
+ oa = builtin_anewarray(count, class_java_lang_reflect_Field);
+
+ if (oa == NULL)
+ return NULL;
+
+ /* Get the fields and store them in the array. */
+
+ for (i = 0, index = 0; i < c->fieldscount; i++) {
+ f = &(c->fields[i]);
+
+ if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
+ // Create a java.lang.reflect.Field object.
+
+ java_lang_reflect_Field rf(f);
+
+ /* Store object into array. */
+
+ array_objectarray_element_set(oa, index, rf.get_handle());
+ index++;
+ }
+ }
+
+ return oa;
+}
+#endif
+
+
+/* class_get_declaredmethods ***************************************************
+
+ Return an array of declared methods of the given class.
+
+ ARGUMENTS:
+ c ............ class to get the methods of
+ publicOnly ... show only public methods
+
+ RETURN:
+ array of java.lang.reflect.Method
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
+{
+ java_handle_objectarray_t *oa; /* result: array of Method-objects */
+ methodinfo *m; /* the current method to be represented */
+ int count;
+ int index;
+ int i;
+
+ /* JOWENN: array classes do not declare methods according to mauve
+ test. It should be considered, if we should return to my old
+ clone method overriding instead of declaring it as a member
+ function. */
+
+ if (class_is_array(c))
+ return builtin_anewarray(0, class_java_lang_reflect_Method);
+
+ /* Determine number of methods. */
+
+ count = 0;
+
+ for (i = 0; i < c->methodscount; i++) {
+ m = &(c->methods[i]);
+
+ if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
+ ((m->name != utf_init) && (m->name != utf_clinit)) &&
+ !(m->flags & ACC_MIRANDA))
+ count++;
+ }
+
+ /* Create array of methods. */
+
+ oa = builtin_anewarray(count, class_java_lang_reflect_Method);
+
+ if (oa == NULL)
+ return NULL;
+
+ /* Get the methods and store them in the array. */
+
+ for (i = 0, index = 0; i < c->methodscount; i++) {
+ m = &(c->methods[i]);
+
+ if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
+ ((m->name != utf_init) && (m->name != utf_clinit)) &&
+ !(m->flags & ACC_MIRANDA)) {
+ // Create java.lang.reflect.Method object.
+
+ java_lang_reflect_Method rm(m);
+
+ /* Store object into array. */
+
+ array_objectarray_element_set(oa, index, rm.get_handle());
+ index++;
+ }
+ }
+
+ return oa;
+}
+#endif
+
+
+/* class_get_declaringclass ****************************************************
+
+ If the class or interface given is a member of another class,
+ return the declaring class. For array and primitive classes return
+ NULL.
+
+*******************************************************************************/
+
+classinfo *class_get_declaringclass(classinfo *c)
+{
+ classref_or_classinfo cr;
+ classinfo *dc;
+
+ /* Get declaring class. */
+
+ cr = c->declaringclass;
+
+ if (cr.any == NULL)
+ return NULL;
+
+ /* Resolve the class if necessary. */
+
+ if (IS_CLASSREF(cr)) {
+/* dc = resolve_classref_eager(cr.ref); */
+ dc = resolve_classref_or_classinfo_eager(cr, true);
+
+ if (dc == NULL)
+ return NULL;
+
+ /* Store the resolved class in the class structure. */
+
+ cr.cls = dc;
+ }
+
+ dc = cr.cls;
+
+ return dc;
+}
+
+
+/* class_get_enclosingclass ****************************************************
+
+ Return the enclosing class for the given class.
+
+*******************************************************************************/
+
+classinfo *class_get_enclosingclass(classinfo *c)
+{
+ classref_or_classinfo cr;
+ classinfo *ec;
+
+ /* Get enclosing class. */
+
+ cr = c->enclosingclass;
+
+ if (cr.any == NULL)
+ return NULL;
+
+ /* Resolve the class if necessary. */
+
+ if (IS_CLASSREF(cr)) {
+/* ec = resolve_classref_eager(cr.ref); */
+ ec = resolve_classref_or_classinfo_eager(cr, true);
+
+ if (ec == NULL)
+ return NULL;
+
+ /* Store the resolved class in the class structure. */
+
+ cr.cls = ec;
+ }
+
+ ec = cr.cls;
+
+ return ec;
+}
+
+
+/**
+ * Return the enclosing constructor as java.lang.reflect.Constructor
+ * object for the given class.
+ *
+ * @param c class to return the enclosing constructor for
+ *
+ * @return java.lang.reflect.Constructor object of the enclosing
+ * constructor
+ */
+#if defined(ENABLE_JAVASE)
+java_handle_t* class_get_enclosingconstructor(classinfo *c)
+{
+ methodinfo* m;
+
+ m = class_get_enclosingmethod_raw(c);
+
+ if (m == NULL)
+ return NULL;
+
+ /* Check for <init>. */
+
+ if (m->name != utf_init)
+ return NULL;
+
+ // Create a java.lang.reflect.Constructor object.
+
+ java_lang_reflect_Constructor rc(m);
+
+ return rc.get_handle();
+}
+#endif
+
+
+/* class_get_enclosingmethod ***************************************************
+
+ Return the enclosing method for the given class.
+
+ IN:
+ c ... class to return the enclosing method for
+
+ RETURN:
+ methodinfo of the enclosing method
+
+*******************************************************************************/
+
+methodinfo *class_get_enclosingmethod_raw(classinfo *c)
+{
+ constant_nameandtype *cn;
+ classinfo *ec;
+ methodinfo *m;
+
+ /* get enclosing class and method */
+
+ ec = class_get_enclosingclass(c);
+ cn = c->enclosingmethod;
+
+ /* check for enclosing class and method */
+
+ if (ec == NULL)
+ return NULL;
+
+ if (cn == NULL)
+ return NULL;
+
+ /* find method in enclosing class */
+
+ m = class_findmethod(ec, cn->name, cn->descriptor);
+
+ if (m == NULL) {
+ exceptions_throw_internalerror("Enclosing method doesn't exist");
+ return NULL;
+ }
+
+ return m;
+}
+
+
+/**
+ * Return the enclosing method as java.lang.reflect.Method object for
+ * the given class.
+ *
+ * @param c class to return the enclosing method for
+ *
+ * @return java.lang.reflect.Method object of the enclosing method
+ */
+#if defined(ENABLE_JAVASE)
+java_handle_t* class_get_enclosingmethod(classinfo *c)
+{
+ methodinfo* m;
+
+ m = class_get_enclosingmethod_raw(c);
+
+ if (m == NULL)
+ return NULL;
+
+ /* check for <init> */
+
+ if (m->name == utf_init)
+ return NULL;
+
+ // Create a java.lang.reflect.Method object.
+
+ java_lang_reflect_Method rm(m);
+
+ return rm.get_handle();
+}
+#endif
+
+
+/* class_get_interfaces ********************************************************
+
+ Return an array of interfaces of the given class.
+
+*******************************************************************************/
+
+java_handle_objectarray_t *class_get_interfaces(classinfo *c)
+{
+ classinfo *ic;
+ java_handle_objectarray_t *oa;
+ u4 i;
+
+ if (!(c->state & CLASS_LINKED))
+ if (!link_class(c))
+ return NULL;
+
+ oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
+
+ if (oa == NULL)
+ return NULL;
+
+ for (i = 0; i < c->interfacescount; i++) {
+ ic = c->interfaces[i];
+
+ LLNI_array_direct(oa, i) = (java_object_t *) ic;
+ }
+
+ return oa;
+}
+
+
+/* class_get_annotations *******************************************************
+
+ Get the unparsed declared annotations in a byte array
+ of the given class.
+
+ IN:
+ c........the class of which the annotations should be returned
+
+ RETURN VALUE:
+ The unparsed declared annotations in a byte array
+ (or NULL if there aren't any).
+
+*******************************************************************************/
+
+java_handle_bytearray_t *class_get_annotations(classinfo *c)
+{
+#if defined(ENABLE_ANNOTATIONS)
+ java_handle_t *annotations; /* unparsed annotations */
+
+ LLNI_classinfo_field_get(c, annotations, annotations);
+
+ return (java_handle_bytearray_t*)annotations;
+#else
+ return NULL;
+#endif
+}
+
+
+/* class_get_modifiers *********************************************************
+
+ Get the modifier flags of the given class.
+
+ IN:
+ c....the class of which the modifier flags should be returned
+ ignoreInnerClassesAttrib
+ RETURN VALUE:
+ modifier flags
+
+*******************************************************************************/
+
+int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
+{
+ classref_or_classinfo inner;
+ classref_or_classinfo outer;
+ utf *innername;
+ int i;
+
+ if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
+ /* search for passed class as inner class */
+
+ for (i = 0; i < c->innerclasscount; i++) {
+ inner = c->innerclass[i].inner_class;
+ outer = c->innerclass[i].outer_class;
+
+ /* Check if inner is a classref or a real class and get
+ the name of the structure */
+
+ innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
+
+ /* innerclass is this class */
+
+ if (innername == c->name) {
+ /* has the class actually an outer class? */
+
+ if (outer.any)
+ /* return flags got from the outer class file */
+ return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
+ else
+ return c->flags & ACC_CLASS_REFLECT_MASK;
+ }
+ }
+ }
+
+ /* passed class is no inner class or it was not requested */
+
+ return c->flags & ACC_CLASS_REFLECT_MASK;
+}
+
+
+/* class_get_signature *********************************************************
+
+ Return the signature of the given class. For array and primitive
+ classes return NULL.
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+utf *class_get_signature(classinfo *c)
+{
+ /* For array and primitive classes return NULL. */
+
+ if (class_is_array(c) || class_is_primitive(c))
+ return NULL;
+
+ return c->signature;
+}
+#endif
+
+
+/* class_printflags ************************************************************
+
+ Prints flags of a class.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_printflags(classinfo *c)
+{
+ if (c == NULL) {
+ printf("NULL");
+ return;
+ }
+
+ if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
+ if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
+ if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
+ if (c->flags & ACC_STATIC) printf(" STATIC");
+ if (c->flags & ACC_FINAL) printf(" FINAL");
+ if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
+ if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
+ if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
+ if (c->flags & ACC_NATIVE) printf(" NATIVE");
+ if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
+ if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
+}
+#endif
+
+
+/* class_print *****************************************************************
+
+ Prints classname plus flags.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_print(classinfo *c)
+{
+ if (c == NULL) {
+ printf("NULL");
+ return;
+ }
+
+ utf_display_printable_ascii(c->name);
+ class_printflags(c);
+}
+#endif
+
+
+/* class_classref_print ********************************************************
+
+ Prints classname plus referer class.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_classref_print(constant_classref *cr)
+{
+ if (cr == NULL) {
+ printf("NULL");
+ return;
+ }
+
+ utf_display_printable_ascii(cr->name);
+ printf("(ref.by ");
+ if (cr->referer)
+ class_print(cr->referer);
+ else
+ printf("NULL");
+ printf(")");
+}
+#endif
+
+
+/* class_println ***************************************************************
+
+ Prints classname plus flags and new line.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_println(classinfo *c)
+{
+ class_print(c);
+ printf("\n");
+}
+#endif
+
+
+/* class_classref_println ******************************************************
+
+ Prints classname plus referer class and new line.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_classref_println(constant_classref *cr)
+{
+ class_classref_print(cr);
+ printf("\n");
+}
+#endif
+
+
+/* class_classref_or_classinfo_print *******************************************
+
+ Prints classname plus referer class.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_classref_or_classinfo_print(classref_or_classinfo c)
+{
+ if (c.any == NULL) {
+ printf("(classref_or_classinfo) NULL");
+ return;
+ }
+ if (IS_CLASSREF(c))
+ class_classref_print(c.ref);
+ else
+ class_print(c.cls);
+}
+#endif
+
+
+/* class_classref_or_classinfo_println *****************************************
+
+ Prints classname plus referer class and a newline.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_classref_or_classinfo_println(classref_or_classinfo c)
+{
+ class_classref_or_classinfo_print(c);
+ printf("\n");
+}
+#endif
+
+
+/* class_showconstantpool ******************************************************
+
+ Dump the constant pool of the given class to stdout.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_showconstantpool (classinfo *c)
+{
+ u4 i;
+ void* e;
+
+ printf ("---- dump of constant pool ----\n");
+
+ for (i=0; i<c->cpcount; i++) {
+ printf ("#%d: ", (int) i);
+
+ e = c -> cpinfos [i];
+ if (e) {
+
+ switch (c -> cptags [i]) {
+ case CONSTANT_Class:
+ printf ("Classreference -> ");
+ utf_display_printable_ascii ( ((constant_classref*)e) -> name );
+ break;
+ case CONSTANT_Fieldref:
+ printf ("Fieldref -> ");
+ field_fieldref_print((constant_FMIref *) e);
+ break;
+ case CONSTANT_Methodref:
+ printf ("Methodref -> ");
+ method_methodref_print((constant_FMIref *) e);
+ break;
+ case CONSTANT_InterfaceMethodref:
+ printf ("InterfaceMethod -> ");
+ method_methodref_print((constant_FMIref *) e);
+ break;
+ case CONSTANT_String:
+ printf ("String -> ");
+ utf_display_printable_ascii ((utf*) e);
+ break;
+ case CONSTANT_Integer:
+ printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
+ break;
+ case CONSTANT_Float:
+ printf ("Float -> %f", ((constant_float*)e) -> value);
+ break;
+ case CONSTANT_Double:
+ printf ("Double -> %f", ((constant_double*)e) -> value);
+ break;
+ case CONSTANT_Long:
+ printf ("Long -> %ld", (long int) ((constant_long*)e) -> value);
+ break;
+ case CONSTANT_NameAndType:
+ {
+ constant_nameandtype *cnt = (constant_nameandtype *) e;
+ printf ("NameAndType: ");
+ utf_display_printable_ascii (cnt->name);
+ printf (" ");
+ utf_display_printable_ascii (cnt->descriptor);
+ }
+ break;
+ case CONSTANT_Utf8:
+ printf ("Utf8 -> ");
+ utf_display_printable_ascii ((utf*) e);
+ break;
+ default:
+ log_text("Invalid type of ConstantPool-Entry");
+ assert(0);
+ }
+ }
+
+ printf ("\n");
+ }
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* class_showmethods ***********************************************************
+
+ Dump info about the fields and methods of the given class to stdout.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_showmethods (classinfo *c)
+{
+ s4 i;
+
+ printf("--------- Fields and Methods ----------------\n");
+ printf("Flags: ");
+ class_printflags(c);
+ printf("\n");
+
+ printf("This: ");
+ utf_display_printable_ascii(c->name);
+ printf("\n");
+
+ if (c->super) {
+ printf("Super: ");
+ utf_display_printable_ascii(c->super->name);
+ printf ("\n");
+ }
+
+ printf("Index: %d\n", c->index);
+
+ printf("Interfaces:\n");
+ for (i = 0; i < c->interfacescount; i++) {
+ printf(" ");
+ utf_display_printable_ascii(c->interfaces[i]->name);
+ printf (" (%d)\n", c->interfaces[i]->index);
+ }
+
+ printf("Fields:\n");
+ for (i = 0; i < c->fieldscount; i++)
+ field_println(&(c->fields[i]));
+
+ printf("Methods:\n");
+ for (i = 0; i < c->methodscount; i++) {
+ methodinfo *m = &(c->methods[i]);
+
+ if (!(m->flags & ACC_STATIC))
+ printf("vftblindex: %d ", m->vftblindex);
+
+ method_println(m);
+ }
+
+ printf ("Virtual function table:\n");
+ for (i = 0; i < c->vftbl->vftbllength; i++)
+ printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
+}
+#endif /* !defined(NDEBUG) */
+
+
+/*
+ * 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/class.h - class related functions header
-
- Copyright (C) 1996-2005, 2006, 2007, 2008
- CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
- 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.
-
-*/
-
-
-#ifndef _CLASS_H
-#define _CLASS_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct classinfo classinfo;
-typedef struct innerclassinfo innerclassinfo;
-typedef struct extra_classref extra_classref;
-
-
-#include "config.h"
-
-#include <stdint.h>
-
-#include "vm/types.h"
-
-#if defined(ENABLE_JAVASE)
-# include "vm/annotation.h"
-#endif
-
-#include "vm/field.hpp"
-#include "vm/global.h"
-#include "vm/linker.h"
-#include "vm/loader.hpp"
-#include "vm/method.h"
-#include "vm/references.h"
-#include "vm/string.hpp"
-#include "vm/utf8.h"
-
-
-/* class state defines ********************************************************/
-
-#define CLASS_LOADING 0x0001
-#define CLASS_LOADED 0x0002
-#define CLASS_LINKING 0x0004
-#define CLASS_LINKED 0x0008
-#define CLASS_INITIALIZING 0x0010
-#define CLASS_INITIALIZED 0x0020
-#define CLASS_ERROR 0x0040
-
-
-/* some macros ****************************************************************/
-
-#define CLASS_IS_OR_ALMOST_INITIALIZED(c) \
- (((c)->state & CLASS_INITIALIZING) || ((c)->state & CLASS_INITIALIZED))
-
-
-/* classinfo ******************************************************************/
-
-/* We define this dummy structure of java_lang_Class so we can
- bootstrap cacaoh without needing a java_lang_Class.h file. Whether
- the size of the dummy structure is big enough is checked during
- runtime in vm_create. */
-
-typedef struct {
- java_object_t header;
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
- intptr_t padding[4];
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
- intptr_t padding[19];
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
- intptr_t padding[3];
-#else
-# error unknown classpath configuration
-#endif
-} dummy_java_lang_Class;
-
-struct classinfo { /* class structure */
- dummy_java_lang_Class object;
-
- s4 flags; /* ACC flags */
- utf *name; /* class name */
-
- s4 cpcount; /* number of entries in constant pool */
- u1 *cptags; /* constant pool tags */
- void* *cpinfos; /* pointer to constant pool info structures */
-
- s4 classrefcount; /* number of symbolic class references */
- constant_classref *classrefs; /* table of symbolic class references */
- extra_classref *extclassrefs; /* additional classrefs */
- s4 parseddescsize; /* size of the parsed descriptors block */
- u1 *parseddescs; /* parsed descriptors */
-
- classinfo *super; /* super class */
- classinfo *sub; /* sub class pointer */
- classinfo *nextsub; /* pointer to next class in sub class list */
-
- int32_t interfacescount; /* number of interfaces */
- classinfo **interfaces; /* super interfaces */
-
- int32_t fieldscount; /* number of fields */
- fieldinfo *fields; /* field table */
-
- int32_t methodscount; /* number of methods */
- methodinfo *methods; /* method table */
-
- s4 state; /* current class state */
- s4 index; /* hierarchy depth (classes) or index */
- /* (interfaces) */
- s4 instancesize; /* size of an instance of this class */
-
- vftbl_t *vftbl; /* pointer to virtual function table */
-
- methodinfo *finalizer; /* finalizer method */
-
- u2 innerclasscount; /* number of inner classes */
- innerclassinfo *innerclass;
-
- classref_or_classinfo declaringclass;
- classref_or_classinfo enclosingclass; /* enclosing class */
- constant_nameandtype *enclosingmethod; /* enclosing method */
-
- utf *packagename; /* full name of the package */
- utf *sourcefile; /* SourceFile attribute */
-#if defined(ENABLE_JAVASE)
- utf *signature; /* Signature attribute */
-#if defined(ENABLE_ANNOTATIONS)
- /* All the annotation attributes are NULL (and not a zero length array) */
- /* if there is nothing. */
- java_object_t *annotations; /* annotations of this class */
-
- java_object_t *method_annotations; /* array of annotations of the methods */
- java_object_t *method_parameterannotations; /* array of parameter */
- /* annotations of the methods */
- java_object_t *method_annotationdefaults; /* array of annotation default */
- /* values of the methods */
-
- java_object_t *field_annotations; /* array of annotations of the fields */
-
-#endif
-#endif
- classloader_t *classloader; /* NULL for bootstrap classloader */
-
-#if defined(ENABLE_JAVASE)
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
- java_object_t *protectiondomain;
- java_objectarray_t *signers;
-# endif
-#endif
-};
-
-
-/* innerclassinfo *************************************************************/
-
-struct innerclassinfo {
- classref_or_classinfo inner_class; /* inner class pointer */
- classref_or_classinfo outer_class; /* outer class pointer */
- utf *name; /* innerclass name */
- s4 flags; /* ACC flags */
-};
-
-
-/* extra_classref **************************************************************
-
- for classrefs not occurring within descriptors
-
-*******************************************************************************/
-
-struct extra_classref {
- extra_classref *next;
- constant_classref classref;
-};
-
-
-/* inline functions ***********************************************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Returns the classname of the class, where slashes ('/') are
- * replaced by dots ('.').
- *
- * @param c class to get name of
- * @return classname
- */
-inline static java_handle_t* class_get_classname(classinfo* c)
-{
- java_handle_t *s;
-
- /* Create a java string. */
-
- s = javastring_new_slash_to_dot(c->name);
-
- return s;
-}
-
-
-/* class_is_primitive **********************************************************
-
- Checks if the given class is a primitive class.
-
-*******************************************************************************/
-
-static inline bool class_is_primitive(classinfo *c)
-{
- if (c->flags & ACC_CLASS_PRIMITIVE)
- return true;
-
- return false;
-}
-
-
-/* class_is_anonymousclass *****************************************************
-
- Checks if the given class is an anonymous class.
-
-*******************************************************************************/
-
-static inline bool class_is_anonymousclass(classinfo *c)
-{
- if (c->flags & ACC_CLASS_ANONYMOUS)
- return true;
-
- return false;
-}
-
-
-/* class_is_array **************************************************************
-
- Checks if the given class is an array class.
-
-*******************************************************************************/
-
-static inline bool class_is_array(classinfo *c)
-{
- if (!(c->state & CLASS_LINKED))
- if (!link_class(c))
- return false;
-
- return (c->vftbl->arraydesc != NULL);
-}
-
-
-/* class_is_interface **********************************************************
-
- Checks if the given class is an interface.
-
-*******************************************************************************/
-
-static inline bool class_is_interface(classinfo *c)
-{
- if (c->flags & ACC_INTERFACE)
- return true;
-
- return false;
-}
-
-
-/* class_is_localclass *********************************************************
-
- Checks if the given class is a local class.
-
-*******************************************************************************/
-
-static inline bool class_is_localclass(classinfo *c)
-{
- if ((c->enclosingmethod != NULL) && !class_is_anonymousclass(c))
- return true;
-
- return false;
-}
-
-
-/* class_is_memberclass ********************************************************
-
- Checks if the given class is a member class.
-
-*******************************************************************************/
-
-static inline bool class_is_memberclass(classinfo *c)
-{
- if (c->flags & ACC_CLASS_MEMBER)
- return true;
-
- return false;
-}
-
-
-/* class_get_classloader *******************************************************
-
- Return the classloader of the given class.
-
-*******************************************************************************/
-
-static inline classloader_t *class_get_classloader(classinfo *c)
-{
- classloader_t *cl;
-
- cl = c->classloader;
-
- /* The classloader may be NULL. */
-
- return cl;
-}
-
-
-/* class_get_superclass ********************************************************
-
- Return the super class of the given class.
-
-*******************************************************************************/
-
-static inline classinfo *class_get_superclass(classinfo *c)
-{
- /* For interfaces we return NULL. */
-
- if (c->flags & ACC_INTERFACE)
- return NULL;
-
- /* For java/lang/Object, primitive-type and Void classes c->super
- is NULL and we return NULL. */
-
- return c->super;
-}
-
-
-/* function prototypes ********************************************************/
-
-classinfo *class_create_classinfo(utf *u);
-void class_postset_header_vftbl(void);
-classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd);
-void class_set_packagename(classinfo *c);
-
-bool class_load_attributes(classbuffer *cb);
-
-/* retrieve constantpool element */
-void* class_getconstant(classinfo *c, u4 pos, u4 ctype);
-void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype);
-
-/* frees all resources used by the class */
-void class_free(classinfo *);
-
-/* return an array class with the given component class */
-classinfo *class_array_of(classinfo *component,bool link);
-
-/* return an array class with the given dimension and element class */
-classinfo *class_multiarray_of(s4 dim, classinfo *element,bool link);
-
-/* return a classref for the given class name */
-/* (does a linear search!) */
-constant_classref *class_lookup_classref(classinfo *cls,utf *name);
-
-/* return a classref for the given class name */
-/* (does a linear search!) */
-constant_classref *class_get_classref(classinfo *cls,utf *name);
-
-/* return a classref to the class itself */
-/* (does a linear search!) */
-constant_classref *class_get_self_classref(classinfo *cls);
-
-/* return a classref for an array with the given dimension of with the */
-/* given component type */
-constant_classref *class_get_classref_multiarray_of(s4 dim,constant_classref *ref);
-
-/* return a classref for the component type of the given array type */
-constant_classref *class_get_classref_component_of(constant_classref *ref);
-
-/* get a class' field by name and descriptor */
-fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc);
-
-/* search 'classinfo'-structure for a field with the specified name */
-fieldinfo *class_findfield_by_name(classinfo *c, utf *name);
-
-/* search class for a field */
-fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer);
-
-/* search for a method with a specified name and descriptor */
-methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc);
-methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *dest);
-methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *dest, classinfo *referer, bool throwexception);
-methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *dest, classinfo *referer, bool throwexception);
-
-bool class_issubclass(classinfo *sub, classinfo *super);
-bool class_isanysubclass(classinfo *sub, classinfo *super);
-bool class_is_assignable_from(classinfo *to, classinfo *from);
-bool class_is_instance(classinfo *c, java_handle_t *h);
-
-classloader_t *class_get_classloader(classinfo *c);
-classinfo *class_get_superclass(classinfo *c);
-classinfo *class_get_componenttype(classinfo *c);
-java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly);
-java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly);
-java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly);
-java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly);
-classinfo *class_get_declaringclass(classinfo *c);
-classinfo *class_get_enclosingclass(classinfo *c);
-java_handle_t* class_get_enclosingconstructor(classinfo *c);
-methodinfo* class_get_enclosingmethod_raw(classinfo *c);
-java_handle_t* class_get_enclosingmethod(classinfo *c);
-java_handle_objectarray_t *class_get_interfaces(classinfo *c);
-java_handle_bytearray_t *class_get_annotations(classinfo *c);
-int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib);
-java_handle_t *class_get_name(classinfo *c);
-
-#if defined(ENABLE_JAVASE)
-utf *class_get_signature(classinfo *c);
-#endif
-
-/* some debugging functions */
-
-#if !defined(NDEBUG)
-void class_printflags(classinfo *c);
-void class_print(classinfo *c);
-void class_println(classinfo *c);
-void class_classref_print(constant_classref *cr);
-void class_classref_println(constant_classref *cr);
-void class_classref_or_classinfo_print(classref_or_classinfo c);
-void class_classref_or_classinfo_println(classref_or_classinfo c);
-#endif
-
-/* debug purposes */
-void class_showmethods(classinfo *c);
-void class_showconstantpool(classinfo *c);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CLASS_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:
- */
--- /dev/null
+/* src/vm/class.hpp - class related functions header
+
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+ 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.
+
+*/
+
+
+#ifndef _CLASS_HPP
+#define _CLASS_HPP
+
+/* forward typedefs ***********************************************************/
+
+typedef struct classinfo classinfo;
+typedef struct innerclassinfo innerclassinfo;
+typedef struct extra_classref extra_classref;
+
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "vm/types.h"
+
+#if defined(ENABLE_JAVASE)
+# include "vm/annotation.h"
+#endif
+
+#include "vm/field.hpp"
+#include "vm/global.h"
+#include "vm/linker.h"
+#include "vm/loader.hpp"
+#include "vm/method.h"
+#include "vm/references.h"
+#include "vm/string.hpp"
+#include "vm/utf8.h"
+
+
+/* class state defines ********************************************************/
+
+#define CLASS_LOADING 0x0001
+#define CLASS_LOADED 0x0002
+#define CLASS_LINKING 0x0004
+#define CLASS_LINKED 0x0008
+#define CLASS_INITIALIZING 0x0010
+#define CLASS_INITIALIZED 0x0020
+#define CLASS_ERROR 0x0040
+
+
+/* some macros ****************************************************************/
+
+#define CLASS_IS_OR_ALMOST_INITIALIZED(c) \
+ (((c)->state & CLASS_INITIALIZING) || ((c)->state & CLASS_INITIALIZED))
+
+
+/* classinfo ******************************************************************/
+
+/* We define this dummy structure of java_lang_Class so we can
+ bootstrap cacaoh without needing a java_lang_Class.h file. Whether
+ the size of the dummy structure is big enough is checked during
+ runtime in vm_create. */
+
+typedef struct {
+ java_object_t header;
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+ intptr_t padding[4];
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+ intptr_t padding[19];
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+ intptr_t padding[3];
+#else
+# error unknown classpath configuration
+#endif
+} dummy_java_lang_Class;
+
+struct classinfo { /* class structure */
+ dummy_java_lang_Class object;
+
+ s4 flags; /* ACC flags */
+ utf *name; /* class name */
+
+ s4 cpcount; /* number of entries in constant pool */
+ u1 *cptags; /* constant pool tags */
+ void* *cpinfos; /* pointer to constant pool info structures */
+
+ s4 classrefcount; /* number of symbolic class references */
+ constant_classref *classrefs; /* table of symbolic class references */
+ extra_classref *extclassrefs; /* additional classrefs */
+ s4 parseddescsize; /* size of the parsed descriptors block */
+ u1 *parseddescs; /* parsed descriptors */
+
+ classinfo *super; /* super class */
+ classinfo *sub; /* sub class pointer */
+ classinfo *nextsub; /* pointer to next class in sub class list */
+
+ int32_t interfacescount; /* number of interfaces */
+ classinfo **interfaces; /* super interfaces */
+
+ int32_t fieldscount; /* number of fields */
+ fieldinfo *fields; /* field table */
+
+ int32_t methodscount; /* number of methods */
+ methodinfo *methods; /* method table */
+
+ s4 state; /* current class state */
+ s4 index; /* hierarchy depth (classes) or index */
+ /* (interfaces) */
+ s4 instancesize; /* size of an instance of this class */
+
+ vftbl_t *vftbl; /* pointer to virtual function table */
+
+ methodinfo *finalizer; /* finalizer method */
+
+ u2 innerclasscount; /* number of inner classes */
+ innerclassinfo *innerclass;
+
+ classref_or_classinfo declaringclass;
+ classref_or_classinfo enclosingclass; /* enclosing class */
+ constant_nameandtype *enclosingmethod; /* enclosing method */
+
+ utf *packagename; /* full name of the package */
+ utf *sourcefile; /* SourceFile attribute */
+#if defined(ENABLE_JAVASE)
+ utf *signature; /* Signature attribute */
+#if defined(ENABLE_ANNOTATIONS)
+ /* All the annotation attributes are NULL (and not a zero length array) */
+ /* if there is nothing. */
+ java_object_t *annotations; /* annotations of this class */
+
+ java_object_t *method_annotations; /* array of annotations of the methods */
+ java_object_t *method_parameterannotations; /* array of parameter */
+ /* annotations of the methods */
+ java_object_t *method_annotationdefaults; /* array of annotation default */
+ /* values of the methods */
+
+ java_object_t *field_annotations; /* array of annotations of the fields */
+
+#endif
+#endif
+ classloader_t *classloader; /* NULL for bootstrap classloader */
+
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+ java_object_t *protectiondomain;
+ java_objectarray_t *signers;
+# endif
+#endif
+};
+
+
+/* innerclassinfo *************************************************************/
+
+struct innerclassinfo {
+ classref_or_classinfo inner_class; /* inner class pointer */
+ classref_or_classinfo outer_class; /* outer class pointer */
+ utf *name; /* innerclass name */
+ s4 flags; /* ACC flags */
+};
+
+
+/* extra_classref **************************************************************
+
+ for classrefs not occurring within descriptors
+
+*******************************************************************************/
+
+struct extra_classref {
+ extra_classref *next;
+ constant_classref classref;
+};
+
+
+/* inline functions ***********************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Returns the classname of the class, where slashes ('/') are
+ * replaced by dots ('.').
+ *
+ * @param c class to get name of
+ * @return classname
+ */
+inline static java_handle_t* class_get_classname(classinfo* c)
+{
+ java_handle_t *s;
+
+ /* Create a java string. */
+
+ s = javastring_new_slash_to_dot(c->name);
+
+ return s;
+}
+
+
+/* class_is_primitive **********************************************************
+
+ Checks if the given class is a primitive class.
+
+*******************************************************************************/
+
+static inline bool class_is_primitive(classinfo *c)
+{
+ if (c->flags & ACC_CLASS_PRIMITIVE)
+ return true;
+
+ return false;
+}
+
+
+/* class_is_anonymousclass *****************************************************
+
+ Checks if the given class is an anonymous class.
+
+*******************************************************************************/
+
+static inline bool class_is_anonymousclass(classinfo *c)
+{
+ if (c->flags & ACC_CLASS_ANONYMOUS)
+ return true;
+
+ return false;
+}
+
+
+/* class_is_array **************************************************************
+
+ Checks if the given class is an array class.
+
+*******************************************************************************/
+
+static inline bool class_is_array(classinfo *c)
+{
+ if (!(c->state & CLASS_LINKED))
+ if (!link_class(c))
+ return false;
+
+ return (c->vftbl->arraydesc != NULL);
+}
+
+
+/* class_is_interface **********************************************************
+
+ Checks if the given class is an interface.
+
+*******************************************************************************/
+
+static inline bool class_is_interface(classinfo *c)
+{
+ if (c->flags & ACC_INTERFACE)
+ return true;
+
+ return false;
+}
+
+
+/* class_is_localclass *********************************************************
+
+ Checks if the given class is a local class.
+
+*******************************************************************************/
+
+static inline bool class_is_localclass(classinfo *c)
+{
+ if ((c->enclosingmethod != NULL) && !class_is_anonymousclass(c))
+ return true;
+
+ return false;
+}
+
+
+/* class_is_memberclass ********************************************************
+
+ Checks if the given class is a member class.
+
+*******************************************************************************/
+
+static inline bool class_is_memberclass(classinfo *c)
+{
+ if (c->flags & ACC_CLASS_MEMBER)
+ return true;
+
+ return false;
+}
+
+
+/* class_get_classloader *******************************************************
+
+ Return the classloader of the given class.
+
+*******************************************************************************/
+
+static inline classloader_t *class_get_classloader(classinfo *c)
+{
+ classloader_t *cl;
+
+ cl = c->classloader;
+
+ /* The classloader may be NULL. */
+
+ return cl;
+}
+
+
+/* class_get_superclass ********************************************************
+
+ Return the super class of the given class.
+
+*******************************************************************************/
+
+static inline classinfo *class_get_superclass(classinfo *c)
+{
+ /* For interfaces we return NULL. */
+
+ if (c->flags & ACC_INTERFACE)
+ return NULL;
+
+ /* For java/lang/Object, primitive-type and Void classes c->super
+ is NULL and we return NULL. */
+
+ return c->super;
+}
+
+
+/* function prototypes ********************************************************/
+
+classinfo *class_create_classinfo(utf *u);
+void class_postset_header_vftbl(void);
+classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd);
+void class_set_packagename(classinfo *c);
+
+bool class_load_attributes(classbuffer *cb);
+
+/* retrieve constantpool element */
+void* class_getconstant(classinfo *c, u4 pos, u4 ctype);
+void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype);
+
+/* frees all resources used by the class */
+void class_free(classinfo *);
+
+/* return an array class with the given component class */
+classinfo *class_array_of(classinfo *component,bool link);
+
+/* return an array class with the given dimension and element class */
+classinfo *class_multiarray_of(s4 dim, classinfo *element,bool link);
+
+/* return a classref for the given class name */
+/* (does a linear search!) */
+constant_classref *class_lookup_classref(classinfo *cls,utf *name);
+
+/* return a classref for the given class name */
+/* (does a linear search!) */
+constant_classref *class_get_classref(classinfo *cls,utf *name);
+
+/* return a classref to the class itself */
+/* (does a linear search!) */
+constant_classref *class_get_self_classref(classinfo *cls);
+
+/* return a classref for an array with the given dimension of with the */
+/* given component type */
+constant_classref *class_get_classref_multiarray_of(s4 dim,constant_classref *ref);
+
+/* return a classref for the component type of the given array type */
+constant_classref *class_get_classref_component_of(constant_classref *ref);
+
+/* get a class' field by name and descriptor */
+fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc);
+
+/* search 'classinfo'-structure for a field with the specified name */
+fieldinfo *class_findfield_by_name(classinfo *c, utf *name);
+
+/* search class for a field */
+fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer);
+
+/* search for a method with a specified name and descriptor */
+methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc);
+methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *dest);
+methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *dest, classinfo *referer, bool throwexception);
+methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *dest, classinfo *referer, bool throwexception);
+
+bool class_issubclass(classinfo *sub, classinfo *super);
+bool class_isanysubclass(classinfo *sub, classinfo *super);
+bool class_is_assignable_from(classinfo *to, classinfo *from);
+bool class_is_instance(classinfo *c, java_handle_t *h);
+
+classloader_t *class_get_classloader(classinfo *c);
+classinfo *class_get_superclass(classinfo *c);
+classinfo *class_get_componenttype(classinfo *c);
+java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly);
+java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly);
+java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly);
+java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly);
+classinfo *class_get_declaringclass(classinfo *c);
+classinfo *class_get_enclosingclass(classinfo *c);
+java_handle_t* class_get_enclosingconstructor(classinfo *c);
+methodinfo* class_get_enclosingmethod_raw(classinfo *c);
+java_handle_t* class_get_enclosingmethod(classinfo *c);
+java_handle_objectarray_t *class_get_interfaces(classinfo *c);
+java_handle_bytearray_t *class_get_annotations(classinfo *c);
+int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib);
+java_handle_t *class_get_name(classinfo *c);
+
+#if defined(ENABLE_JAVASE)
+utf *class_get_signature(classinfo *c);
+#endif
+
+/* some debugging functions */
+
+#if !defined(NDEBUG)
+void class_printflags(classinfo *c);
+void class_print(classinfo *c);
+void class_println(classinfo *c);
+void class_classref_print(constant_classref *cr);
+void class_classref_println(constant_classref *cr);
+void class_classref_or_classinfo_print(classref_or_classinfo c);
+void class_classref_or_classinfo_println(classref_or_classinfo c);
+#endif
+
+/* debug purposes */
+void class_showmethods(classinfo *c);
+void class_showconstantpool(classinfo *c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CLASS_HPP */
+
+
+/*
+ * 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:
+ */
#include "toolbox/hashtable.h"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "vm/loader.hpp"
#include "vm/references.h"
#include "toolbox/hashtable.h"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "vm/method.h"
#include "vm/references.h"
#include "toolbox/util.h"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/exceptions.hpp"
#include "vm/global.h"
#include "vm/globals.hpp"
#include "vm/annotation.h"
#include "vm/array.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/descriptor.h"
#include "vm/exceptions.hpp"
#include "vm/field.hpp"
#include "vm/types.h"
#include "vm/descriptor.h"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "vm/loader.hpp"
#include "vm/references.h"
#include <stdint.h>
-#include "vm/class.h"
+#include "vm/class.hpp"
// Classes.
#include <stdint.h>
-#include "vm/class.h"
+#include "vm/class.hpp"
// FIXME For now we export them a C symbols.
#include "threads/lock.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/exceptions.hpp"
#include "vm/global.h"
#include "vm/globals.hpp"
extern "C" {
#endif
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "threads/atomic.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/field.hpp"
#include "vm/global.h"
#include "vm/globals.hpp"
#include "native/native.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/field.hpp"
#include "vm/initialize.hpp"
#include "vm/options.h"
#include "native/native.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/field.hpp"
#include "vm/initialize.hpp"
#include "vm/options.h"
#include "vm/array.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/cycles-stats.h"
#include "vm/exceptions.hpp"
#include "vm/global.h"
#include "native/native.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/field.hpp"
#include "vm/initialize.hpp"
#include "vm/options.h"
#include "toolbox/logging.h"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "vm/initialize.hpp"
#include "vm/method.h"
#include "threads/thread.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/linker.h"
#include "vm/loader.hpp"
#include "vm/options.h"
#include "native/native.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/exceptions.hpp"
#include "vm/global.h"
#include "vm/options.h"
typedef s4 Cell;
#endif
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "vm/linker.h"
#include "vm/method.h"
#include "native/native.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/field.hpp"
#include "vm/initialize.hpp"
#include "vm/options.h"
#include "threads/mutex.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "vm/globals.hpp"
#include "vm/initialize.hpp"
#include "native/native.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/field.hpp"
#include "vm/initialize.hpp"
#include "vm/options.h"
#include "threads/lock.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/exceptions.hpp"
#include "vm/options.h"
#include "vm/vm.hpp"
#include "native/native.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/field.hpp"
#include "vm/initialize.hpp"
#include "vm/options.h"
#include "toolbox/bitvector.h"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/descriptor.h"
#include "vm/global.h"
#include "vm/references.h"
#include "config.h"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/classcache.h"
#include "vm/jit/jit.hpp"
#include "threads/thread.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/classcache.h"
#include "vm/method.h"
#include "vm/options.h"
#include "native/native.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/field.hpp"
#include "vm/initialize.hpp"
#include "vm/options.h"
#include "native/native.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/field.hpp"
#include "vm/initialize.hpp"
#include "vm/options.h"
#include "native/native.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/field.hpp"
#include "vm/initialize.hpp"
#include "vm/options.h"
#include "native/native.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/exceptions.hpp"
#include "vm/field.hpp"
#include "vm/initialize.hpp"
#include "vm/array.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/cycles-stats.h"
#include "vm/exceptions.hpp"
#include "vm/globals.hpp"
#include "threads/thread.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "vm/jit/code.hpp"
#include "toolbox/logging.h"
#include "vm/array.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/descriptor.h"
#include "vm/exceptions.hpp"
#include "vm/globals.hpp"
#include "native/native.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/field.hpp"
#include "vm/initialize.hpp"
#include "vm/options.h"
#include "vm/access.h"
#include "vm/array.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/classcache.h"
#include "vm/exceptions.hpp"
#include "vm/globals.hpp"
#include "threads/mutex.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/references.h"
#include "vm/vftbl.hpp"
#include "vm/types.h"
#include "vm/descriptor.h"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "vm/method.h"
#include "vm/references.h"
#include "vm/array.hpp"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/exceptions.hpp"
#include "vm/global.h"
#include "vm/globals.hpp"
#include "native/llni.h"
#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "vm/globals.hpp"
#include "vm/javaobjects.hpp"
#include <stdint.h>
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "vm/linker.h"
#include "vm/utf8.h"
#include "toolbox/util.h"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "vm/method.h"
#include "vm/options.h"
#include "config.h"
#include "vm/types.h"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/descriptor.h"
#include "vm/field.hpp"
#include "vm/global.h"
#include "config.h"
#include "vm/types.h"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/field.hpp"
#include "vm/global.h"
#include "vm/method.h"
#include "mm/memory.h"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/exceptions.hpp"
#include "vm/method.h"
#include "vm/options.h"
#include "toolbox/logging.h"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/field.hpp"
#include "vm/global.h"
#include "vm/method.h"
#include "toolbox/hashtable.h"
#include "toolbox/list.hpp"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "vm/loader.hpp"
*******************************************************************************/
// Includes.
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/references.h"
struct _vftbl {
/* We need to check if the actual size of a java.lang.Class object
is smaller or equal than the assumption made in
- src/vm/class.h. */
+ src/vm/class.hpp. */
#warning FIXME We need to check the size of java.lang.Class!!!
// if (sizeof(java_lang_Class) > sizeof(dummy_java_lang_Class))
#include "toolbox/hashtable.h"
-#include "vm/class.h"
+#include "vm/class.hpp"
#include "vm/global.h"
#include "vm/loader.hpp"
#include "vm/suck.hpp"