From: Michael Starzinger Date: Sat, 27 Dec 2008 14:38:41 +0000 (+0100) Subject: * src/vm/class.hpp (class_is_arraycompatible): New method (moved from builtin). X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=cacao.git;a=commitdiff_plain;h=1a841b897ae73436107ccf8ba070042d681b18e3 * src/vm/class.hpp (class_is_arraycompatible): New method (moved from builtin). * src/vm/class.hpp (class_is_arraycompatible): Likewise. (class_is_assignable_from): Fixed for array classes. (class_is_instance): Likewise. * src/vm/jit/builtin.cpp (builtin_descriptorscompatible): Removed. (builtin_fast_arraycheckcast): Switched to new method. (builtin_fast_canstore): Likewise. --- diff --git a/src/vm/class.cpp b/src/vm/class.cpp index 0c3b13494..35ef8de90 100644 --- a/src/vm/class.cpp +++ b/src/vm/class.cpp @@ -1486,6 +1486,53 @@ bool class_isanysubclass(classinfo *sub, classinfo *super) } +/* 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 1; + + if (desc->arraytype != target->arraytype) + return 0; + + if (desc->arraytype != ARRAYTYPE_OBJECT) + return 1; + + /* {both arrays are arrays of references} */ + + if (desc->dimension == target->dimension) { + if (!desc->elementvftbl) + return 0; + /* an array which contains elements of interface types is + allowed to be casted to Object (JOWENN)*/ + + if ((desc->elementvftbl->baseval < 0) && + (target->elementvftbl->baseval == 1)) + return 1; + + return class_isanysubclass(desc->elementvftbl->clazz, + target->elementvftbl->clazz); + } + + if (desc->dimension < target->dimension) + return 0; + + /* {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 @@ -1511,7 +1558,12 @@ bool class_is_assignable_from(classinfo *to, classinfo *from) 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)) + return class_is_arraycompatible(from->vftbl->arraydesc, to->vftbl->arraydesc); + else + return class_isanysubclass(from, to); } @@ -1535,7 +1587,12 @@ bool class_is_instance(classinfo *c, java_handle_t *h) 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); } diff --git a/src/vm/class.hpp b/src/vm/class.hpp index b09bcca47..85f05618c 100644 --- a/src/vm/class.hpp +++ b/src/vm/class.hpp @@ -399,6 +399,7 @@ methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *dest, cla bool class_issubclass(classinfo *sub, classinfo *super); bool class_isanysubclass(classinfo *sub, classinfo *super); +bool class_is_arraycompatible(arraydescriptor *desc, arraydescriptor *target); bool class_is_assignable_from(classinfo *to, classinfo *from); bool class_is_instance(classinfo *c, java_handle_t *h); diff --git a/src/vm/jit/builtin.cpp b/src/vm/jit/builtin.cpp index 5747a032b..bdfb79a4b 100644 --- a/src/vm/jit/builtin.cpp +++ b/src/vm/jit/builtin.cpp @@ -441,53 +441,6 @@ bool builtin_checkcast(java_handle_t *o, classinfo *c) } -/* builtin_descriptorscompatible *********************************************** - - Checks if two array type descriptors are assignment compatible. - - RETURN VALUE: - 1......target = desc is possible - 0......otherwise - -*******************************************************************************/ - -static bool builtin_descriptorscompatible(arraydescriptor *desc, arraydescriptor *target) -{ - if (desc == target) - return 1; - - if (desc->arraytype != target->arraytype) - return 0; - - if (desc->arraytype != ARRAYTYPE_OBJECT) - return 1; - - /* {both arrays are arrays of references} */ - - if (desc->dimension == target->dimension) { - if (!desc->elementvftbl) - return 0; - /* an array which contains elements of interface types is - allowed to be casted to Object (JOWENN)*/ - - if ((desc->elementvftbl->baseval < 0) && - (target->elementvftbl->baseval == 1)) - return 1; - - return class_isanysubclass(desc->elementvftbl->clazz, - target->elementvftbl->clazz); - } - - if (desc->dimension < target->dimension) - return 0; - - /* {desc has higher dimension than target} */ - - return class_isanysubclass(pseudo_class_Arraystub, - target->elementvftbl->clazz); -} - - /* builtin_arraycheckcast ****************************************************** Checks if an object is really a subtype of the requested array @@ -515,7 +468,7 @@ bool builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass) if (desc == NULL) return 0; - return builtin_descriptorscompatible(desc, targetclass->vftbl->arraydesc); + return class_is_arraycompatible(desc, targetclass->vftbl->arraydesc); } @@ -738,7 +691,7 @@ bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o) else { /* {o is an array} */ - result = builtin_descriptorscompatible(valuedesc, componentvftbl->arraydesc); + result = class_is_arraycompatible(valuedesc, componentvftbl->arraydesc); } /* return result */