#include "arch.h"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
#include "native/llni.h"
#include "threads/lock.hpp"
#include "threads/mutex.hpp"
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
#include "vm/array.hpp"
#include "vm/jit/builtin.hpp"
#include "vm/global.h"
#include "vm/globals.hpp"
#include "vm/javaobjects.hpp"
-#include "vm/linker.h"
+#include "vm/linker.hpp"
#include "vm/loader.hpp"
#include "vm/options.h"
#include "vm/resolve.hpp"
bool class_isanysubclass(classinfo *sub, classinfo *super)
{
- uint32_t diffval;
- bool result;
+ bool result;
/* This is the trivial case. */
if (sub->flags & ACC_INTERFACE)
return (super == class_java_lang_Object);
+#if USES_NEW_SUBTYPE
result = fast_subtype_check(sub->vftbl, super->vftbl);
+#else
+ LOCK_CLASSRENUMBER_LOCK;
+
+ uint32_t diffval = sub->vftbl->baseval - super->vftbl->baseval;
+ result = diffval <= (uint32_t) super->vftbl->diffval;
+
+ UNLOCK_CLASSRENUMBER_LOCK;
+#endif
}
return result;
}
+/* class_is_arraycompatible ****************************************************
+
+ Checks if two array type descriptors are assignment compatible.
+
+ RETURN VALUE:
+ true .... target = desc is possible
+ false ... otherwise
+
+*******************************************************************************/
+
+bool class_is_arraycompatible(arraydescriptor *desc, arraydescriptor *target)
+{
+ if (desc == target)
+ return true;
+
+ if (desc->arraytype != target->arraytype)
+ return false;
+
+ if (desc->arraytype != ARRAYTYPE_OBJECT)
+ return true;
+
+ /* {both arrays are arrays of references} */
+
+ if (desc->dimension == target->dimension) {
+ if (!desc->elementvftbl)
+ return false;
+
+ /* an array which contains elements of interface types is
+ allowed to be casted to array of Object (JOWENN) */
+
+ if ((desc->elementvftbl->baseval < 0) &&
+ (target->elementvftbl->baseval == 1))
+ return true;
+
+ return class_isanysubclass(desc->elementvftbl->clazz,
+ target->elementvftbl->clazz);
+ }
+
+ if (desc->dimension < target->dimension)
+ return false;
+
+ /* {desc has higher dimension than target} */
+
+ return class_isanysubclass(pseudo_class_Arraystub,
+ target->elementvftbl->clazz);
+}
+
+
/* class_is_assignable_from ****************************************************
Return whether an instance of the "from" class parameter would be
if (!link_class(from))
return false;
- return class_isanysubclass(from, to);
+ /* Decide whether we are dealing with array types or object types. */
+
+ if (class_is_array(to) && class_is_array(from))
+ return class_is_arraycompatible(from->vftbl->arraydesc, to->vftbl->arraydesc);
+ else
+ return class_isanysubclass(from, to);
}
if (!link_class(c))
return false;
- return builtin_instanceof(h, c);
+ /* Decide whether we are dealing with array types or object types. */
+
+ if (class_is_array(c))
+ return builtin_arrayinstanceof(h, c);
+ else
+ return builtin_instanceof(h, c);
}
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;
/* Allocate Class[] and check for OOM. */
- oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
+ ClassArray declaredclasses(declaredclasscount);
- if (oa == NULL)
+ if (declaredclasses.is_null())
return NULL;
for (i = 0, pos = 0; i < c->innerclasscount; i++) {
if (!link_class(ic))
return NULL;
- LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
+ declaredclasses.set_element(pos++, ic);
}
}
- return oa;
+ return declaredclasses.get_handle();
}
#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;
+ methodinfo* m;
+ int count;
+ int index;
+ int i;
/* Determine number of constructors. */
/* Create array of constructors. */
- oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
+ ObjectArray oa(count, class_java_lang_reflect_Constructor);
- if (oa == NULL)
+ if (oa.is_null())
return NULL;
/* Get the constructors and store them in the array. */
/* Store object into array. */
- array_objectarray_element_set(oa, index, rc.get_handle());
+ oa.set_element(index, rc.get_handle());
index++;
}
}
- return oa;
+ return oa.get_handle();
}
#endif
#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;
+ fieldinfo* f;
+ int count;
+ int index;
+ int i;
/* Determine number of fields. */
/* Create array of fields. */
- oa = builtin_anewarray(count, class_java_lang_reflect_Field);
+ ObjectArray oa(count, class_java_lang_reflect_Field);
- if (oa == NULL)
+ if (oa.is_null())
return NULL;
/* Get the fields and store them in the array. */
/* Store object into array. */
- array_objectarray_element_set(oa, index, rf.get_handle());
+ oa.set_element(index, rf.get_handle());
index++;
}
}
- return oa;
+ return oa.get_handle();
}
#endif
#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;
+ 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);
+ if (class_is_array(c)) {
+ ObjectArray oa(0, class_java_lang_reflect_Method);
+ return oa.get_handle();
+ }
/* Determine number of methods. */
/* Create array of methods. */
- oa = builtin_anewarray(count, class_java_lang_reflect_Method);
+ ObjectArray oa(count, class_java_lang_reflect_Method);
- if (oa == NULL)
+ if (oa.is_null())
return NULL;
/* Get the methods and store them in the array. */
/* Store object into array. */
- array_objectarray_element_set(oa, index, rm.get_handle());
+ oa.set_element(index, rm.get_handle());
index++;
}
}
- return oa;
+ return oa.get_handle();
}
#endif
*******************************************************************************/
-java_handle_objectarray_t *class_get_interfaces(classinfo *c)
+java_handle_objectarray_t* class_get_interfaces(classinfo *c)
{
- classinfo *ic;
- java_handle_objectarray_t *oa;
- u4 i;
+ classinfo* ic;
+ u4 i;
if (!(c->state & CLASS_LINKED))
if (!link_class(c))
return NULL;
- oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
+ ClassArray interfaces(c->interfacescount);
- if (oa == NULL)
+ if (interfaces.is_null())
return NULL;
for (i = 0; i < c->interfacescount; i++) {
ic = c->interfaces[i];
- LLNI_array_direct(oa, i) = (java_object_t *) ic;
+ interfaces.set_element(i, ic);
}
- return oa;
+ return interfaces.get_handle();
}
LLNI_classinfo_field_get(c, annotations, annotations);
- return (java_handle_bytearray_t*)annotations;
+ return (java_handle_bytearray_t*) annotations;
#else
return NULL;
#endif
classref_or_classinfo outer;
utf *innername;
int i;
+ int32_t flags;
+
+ /* default to flags of passed class */
+
+ flags = c->flags;
+
+ /* if requested we check if passed class is inner class */
if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
/* search for passed class as inner 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;
+ flags = c->innerclass[i].flags;
+
+ break;
}
}
}
- /* passed class is no inner class or it was not requested */
+ /* remove ACC_SUPER bit from flags */
- return c->flags & ACC_CLASS_REFLECT_MASK;
+ return flags & ~ACC_SUPER & ACC_CLASS_REFLECT_MASK;
}