+/******************* Function: class_new_array *********************************
+
+ This function is called by class_new to setup an array class.
+
+*******************************************************************************/
+
+void
+class_new_array(classinfo *c)
+{
+ classinfo *comp = NULL;
+ methodinfo *clone;
+ int namelen;
+
+ /* XXX remove logging */
+ /*
+ sprintf(logtext,"new array class: ");
+ utf_sprint(logtext+strlen(logtext),c->name);
+ dolog();
+ */
+
+ /* Array classes are not loaded from classfiles. */
+ list_remove (&unloadedclasses, c);
+
+ /* Check array class name */
+ namelen = c->name->blength;
+ if (namelen < 2 || c->name->text[0] != '[')
+ panic("Invalid array class name.");
+
+ /* Check the component type */
+ switch (c->name->text[1]) {
+ case '[':
+ /* c is an array of arrays. We have to create the component class. */
+ comp = class_new(utf_new(c->name->text + 1,namelen - 1));
+ break;
+
+ case 'L':
+ /* XXX remove logging */
+ /*
+ sprintf(logtext,"Component class: ");
+ utf_sprint(logtext+strlen(logtext),utf_new(c->name->text + 2,namelen - 3));
+ dolog();
+ if (class_get(utf_new(c->name->text + 2,namelen - 3)))
+ log_text("Already created.");
+ */
+
+ /* c is an array of objects. */
+ if (namelen < 4 || c->name->text[namelen-1] != ';')
+ panic("Invalid array class name.");
+ comp = class_new(utf_new(c->name->text + 2,namelen - 3));
+ break;
+ }
+
+ /* Setup the array class */
+ c->super = class_java_lang_Object;
+
+ c->interfacescount = 2;
+ c->interfaces = MNEW(classinfo*,2);
+ c->interfaces[0] = class_java_lang_Cloneable;
+ c->interfaces[1] = class_java_io_Serializable;
+
+ c->methodscount = 1;
+ c->methods = MNEW (methodinfo, c->methodscount);
+
+ clone = c->methods;
+ memset(clone,0,sizeof(methodinfo));
+ clone->flags = ACC_PUBLIC; /* XXX protected? */
+ clone->name = utf_new_char("clone");
+ clone->descriptor = utf_new_char("()Ljava/lang/Object;");
+ clone->class = c;
+ clone->stubroutine = createnativestub(&builtin_clone_array,clone);
+ clone->monoPoly = MONO; /* XXX should be poly? */
+
+ /* XXX: field: length? */
+
+ /* The array class has to be linked */
+ list_addlast(&unlinkedclasses,c);
+
+ /*
+ * Array classes which are created after the other classes have been
+ * loaded and linked are linked explicitely.
+ */
+ if (loader_inited)
+ loader_load(c->name);
+}
+
+/****************** Function: class_link_array *********************************
+
+ This function is called by class_link to create the
+ arraydescriptor for an array class.
+
+ This function returns NULL if the array cannot be linked because
+ the component type has not been linked yet.
+
+*******************************************************************************/
+
+static
+arraydescriptor *
+class_link_array(classinfo *c)
+{
+ classinfo *comp = NULL;
+ int namelen = c->name->blength;
+ arraydescriptor *desc;
+ vftbl *compvftbl;
+
+ /* XXX remove logging */
+
+ /*
+ sprintf(logtext,"linking array class: ");
+ utf_sprint(logtext+strlen(logtext),c->name);
+ dolog();
+ */
+
+
+ /* Check the component type */
+ switch (c->name->text[1]) {
+ case '[':
+ /* c is an array of arrays. */
+ comp = class_get(utf_new(c->name->text + 1,namelen - 1));
+ if (!comp) panic("Could not find component array class.");
+ break;
+
+ case 'L':
+ /* c is an array of objects. */
+ comp = class_get(utf_new(c->name->text + 2,namelen - 3));
+ if (!comp) panic("Could not find component class.");
+ break;
+ }
+
+ /* If the component type has not been linked return NULL */
+ if (comp && !comp->linked)
+ return NULL;
+
+ /* Allocate the arraydescriptor */
+ desc = NEW(arraydescriptor);
+
+ if (comp) {
+ /* c is an array of references */
+ desc->arraytype = ARRAYTYPE_OBJECT;
+ desc->componentsize = sizeof(void*);
+ desc->dataoffset = OFFSET(java_objectarray,data);
+
+ compvftbl = comp->vftbl;
+ if (!compvftbl)
+ panic("Component class has no vftbl.");
+ desc->componentvftbl = compvftbl;
+
+ if (compvftbl->arraydesc) {
+ desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
+ desc->dimension = compvftbl->arraydesc->dimension + 1;
+ }
+ else {
+ desc->elementvftbl = compvftbl;
+ desc->dimension = 1;
+ }
+ }
+ else {
+ /* c is an array of a primitive type */
+ switch (c->name->text[1]) {
+ case 'Z': desc->arraytype = ARRAYTYPE_BOOLEAN;
+ desc->dataoffset = OFFSET(java_booleanarray,data);
+ desc->componentsize = sizeof(u1); break;
+ case 'B': desc->arraytype = ARRAYTYPE_BYTE;
+ desc->dataoffset = OFFSET(java_bytearray,data);
+ desc->componentsize = sizeof(u1); break;
+ case 'C': desc->arraytype = ARRAYTYPE_CHAR;
+ desc->dataoffset = OFFSET(java_chararray,data);
+ desc->componentsize = sizeof(u2); break;
+ case 'D': desc->arraytype = ARRAYTYPE_DOUBLE;
+ desc->dataoffset = OFFSET(java_doublearray,data);
+ desc->componentsize = sizeof(double); break;
+ case 'F': desc->arraytype = ARRAYTYPE_FLOAT;
+ desc->dataoffset = OFFSET(java_floatarray,data);
+ desc->componentsize = sizeof(float); break;
+ case 'I': desc->arraytype = ARRAYTYPE_INT;
+ desc->dataoffset = OFFSET(java_intarray,data);
+ desc->componentsize = sizeof(s4); break;
+ case 'J': desc->arraytype = ARRAYTYPE_LONG;
+ desc->dataoffset = OFFSET(java_longarray,data);
+ desc->componentsize = sizeof(s8); break;
+ case 'S': desc->arraytype = ARRAYTYPE_SHORT;
+ desc->dataoffset = OFFSET(java_shortarray,data);
+ desc->componentsize = sizeof(s2); break;
+ default:
+ panic("Invalid array class name");
+ }
+
+ desc->componentvftbl = NULL;
+ desc->elementvftbl = NULL;
+ desc->dimension = 1;
+ }
+
+ /* XXX remove logging */
+ /*
+ print_arraydescriptor(stdout,desc);
+ printf("\n");
+ */
+
+ return desc;
+}
+