-/********************** function: utf_nextu2 *********************************
-
- read the next unicode character from the utf string and
- increment the utf-string pointer accordingly
-
-******************************************************************************/
-
-u2 utf_nextu2(char **utf_ptr)
-{
- /* uncompressed unicode character */
- u2 unicode_char;
- /* current position in utf text */
- unsigned char *utf = (unsigned char *) (*utf_ptr);
- /* bytes representing the unicode character */
- unsigned char ch1, ch2, ch3;
- /* number of bytes used to represent the unicode character */
- int len;
-
- switch ((ch1 = utf[0]) >> 4) {
- default: /* 1 byte */
- (*utf_ptr)++;
- return ch1;
- case 0xC:
- case 0xD: /* 2 bytes */
- if (((ch2 = utf[1]) & 0xC0) == 0x80) {
- unsigned char high = ch1 & 0x1F;
- unsigned char low = ch2 & 0x3F;
- unicode_char = (high << 6) + low;
- len = 2;
- }
- break;
-
- case 0xE: /* 2 or 3 bytes */
- if (((ch2 = utf[1]) & 0xC0) == 0x80) {
- if (((ch3 = utf[2]) & 0xC0) == 0x80) {
- unsigned char low = ch3 & 0x3f;
- unsigned char mid = ch2 & 0x3f;
- unsigned char high = ch1 & 0x0f;
- unicode_char = (((high << 6) + mid) << 6) + low;
- len = 3;
- } else
- len = 2;
- }
- break;
- }
-
- /* update position in utf-text */
- *utf_ptr = (char *) (utf + len);
- return unicode_char;
-}
-
-/********************* function: is_valid_utf ********************************
-
- return true if the given string is a valid UTF-8 string
-
- utf_ptr...points to first character
- end_pos...points after last character
-
-******************************************************************************/
-
-static unsigned long min_codepoint[6] = {0,1L<<7,1L<<11,1L<<16,1L<<21,1L<<26};
-
-bool
-is_valid_utf(char *utf_ptr,char *end_pos)
-{
- int bytes;
- int len,i;
- char c;
- unsigned long v;
-
- if (end_pos < utf_ptr) return false;
- bytes = end_pos - utf_ptr;
- while (bytes--) {
- c = *utf_ptr++;
- /*dolog("%c %02x",c,c);*/
- if (!c) return false; /* 0x00 is not allowed */
- if ((c & 0x80) == 0) continue; /* ASCII */
-
- if ((c & 0xe0) == 0xc0) len = 1; /* 110x xxxx */
- else if ((c & 0xf0) == 0xe0) len = 2; /* 1110 xxxx */
- else if ((c & 0xf8) == 0xf0) len = 3; /* 1111 0xxx */
- else if ((c & 0xfc) == 0xf8) len = 4; /* 1111 10xx */
- else if ((c & 0xfe) == 0xfc) len = 5; /* 1111 110x */
- else return false; /* invalid leading byte */
-
- if (len > 2) return false; /* Java limitation */
-
- v = (unsigned long)c & (0x3f >> len);
-
- if ((bytes -= len) < 0) return false; /* missing bytes */
-
- for (i = len; i--; ) {
- c = *utf_ptr++;
- /*dolog(" %c %02x",c,c);*/
- if ((c & 0xc0) != 0x80) /* 10xx xxxx */
- return false;
- v = (v<<6) | (c & 0x3f);
- }
-
- /* dolog("v=%d",v);*/
-
- if (v == 0) {
- if (len != 1) return false; /* Java special */
- }
- else {
- if (v < min_codepoint[len]) return false; /* overlong UTF-8 */
- }
-
- /* surrogates in UTF-8 seem to be allowed in Java classfiles */
- /* if (v >= 0xd800 && v <= 0xdfff) return false; */ /* surrogates */
-
- /* even these seem to be allowed */
- /* if (v == 0xfffe || v == 0xffff) return false; */ /* invalid codepoints */
- }
-
- return true;
-}
-
-/******************** Function: class_new **************************************
-
- searches for the class with the specified name in the classes hashtable,
- if there is no such class a new classinfo structure is created and inserted
- into the list of classes to be loaded
-
-*******************************************************************************/
-
-classinfo *class_new(utf *u)
-{
- classinfo *c; /* hashtable element */
- u4 key; /* hashkey computed from classname */
- u4 slot; /* slot in hashtable */
- u2 i;
-
- key = utf_hashkey (u->text, u->blength);
- slot = key & (class_hash.size-1);
- c = class_hash.ptr[slot];
-
- /* search external hash chain for the class */
- while (c) {
- if (c->name->blength == u->blength) {
- for (i=0; i<u->blength; i++)
- if (u->text[i] != c->name->text[i]) goto nomatch;
-
- /* class found in hashtable */
- return c;
- }
-
- nomatch:
- c = c->hashlink; /* next element in external chain */
- }
-
- /* location in hashtable found, create new classinfo structure */
-
-#ifdef STATISTICS
- count_class_infos += sizeof(classinfo);
-#endif
-
- c = GCNEW(classinfo, 1); /*JOWENN: NEW*/
- c->vmClass = 0;
- c->flags = 0;
- c->name = u;
- c->cpcount = 0;
- c->cptags = NULL;
- c->cpinfos = NULL;
- c->super = NULL;
- c->sub = NULL;
- c->nextsub = NULL;
- c->interfacescount = 0;
- c->interfaces = NULL;
- c->fieldscount = 0;
- c->fields = NULL;
- c->methodscount = 0;
- c->methods = NULL;
- c->linked = false;
- c->loaded = false;
- c->index = 0;
- c->instancesize = 0;
- c->header.vftbl = NULL;
- c->innerclasscount = 0;
- c->innerclass = NULL;
- c->vftbl = NULL;
- c->initialized = false;
- c->classvftbl = false;
- c->classUsed = 0;
- c->impldBy = NULL;
-
- /* prepare loading of the class */
- list_addlast(&unloadedclasses, c);
-
- /* insert class into the hashtable */
- c->hashlink = class_hash.ptr[slot];
- class_hash.ptr[slot] = c;
-
- /* update number of hashtable-entries */
- class_hash.entries++;
-
- if (class_hash.entries > (class_hash.size*2)) {
-
- /* reorganization of hashtable, average length of
- the external chains is approx. 2 */
-
- u4 i;
- classinfo *c;
- hashtable newhash; /* the new hashtable */
-
- /* create new hashtable, double the size */
- init_hashtable(&newhash, class_hash.size * 2);
- newhash.entries = class_hash.entries;
-
- /* transfer elements to new hashtable */
- for (i = 0; i < class_hash.size; i++) {
- c = (classinfo*) class_hash.ptr[i];
- while (c) {
- classinfo *nextc = c->hashlink;
- u4 slot = (utf_hashkey(c->name->text, c->name->blength)) & (newhash.size - 1);
-
- c->hashlink = newhash.ptr[slot];
- newhash.ptr[slot] = c;
-
- c = nextc;
- }
- }
-
- /* dispose old table */
- MFREE(class_hash.ptr, void*, class_hash.size);
- class_hash = newhash;
- }
-
- /* Array classes need further initialization. */
- if (u->text[0] == '[')
- class_new_array(c);
-
- return c;
-}
-
-/******************** Function: class_get **************************************
-
- searches for the class with the specified name in the classes hashtable
- if there is no such class NULL is returned
-
-*******************************************************************************/
-
-classinfo *class_get(utf *u)
-{
- classinfo *c; /* hashtable element */
- u4 key; /* hashkey computed from classname */
- u4 slot; /* slot in hashtable */
- u2 i;
-
- key = utf_hashkey (u->text, u->blength);
- slot = key & (class_hash.size-1);
- c = class_hash.ptr[slot];
-
-/*
- log_text("class_get: looking for class:");
- utf_display(u); */
- /* search external hash-chain */
- while (c) {
- if (c->name->blength == u->blength) {
-
- /* compare classnames */
- for (i=0; i<u->blength; i++)
- if (u->text[i] != c->name->text[i]) goto nomatch;
-/*
- log_text("class_get: class found");
- utf_display(u);
- log_text("");
- utf_display(c->name); */
- /* class found in hashtable */
- return c;
- }
-
- nomatch:
- c = c->hashlink;
- }
-
- /* class not found */
- return NULL;
-}
-
-/***************** Function: 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)
-{
- int namelen;
- char *namebuf;
-
- /* Assemble the array class name */
- namelen = component->name->blength;
-
- if (component->name->text[0] == '[') {
- /* the component is itself an array */
- namebuf = DMNEW(char,namelen+1);
- namebuf[0] = '[';
- memcpy(namebuf+1,component->name->text,namelen);
- namelen++;
- }
- else {
- /* the component is a non-array class */
- namebuf = DMNEW(char,namelen+3);
- namebuf[0] = '[';
- namebuf[1] = 'L';
- memcpy(namebuf+2,component->name->text,namelen);
- namebuf[2+namelen] = ';';
- namelen+=3;
- }
-
- return class_new( utf_new(namebuf,namelen) );
-}
-
-/*************** Function: 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(int dim,classinfo *element)
-{
- int namelen;
- char *namebuf;
-
- if (dim<1)
- panic("Invalid array dimension requested");
-
- /* Assemble the array class name */
- namelen = element->name->blength;
-
- if (element->name->text[0] == '[') {
- /* the element is itself an array */
- namebuf = DMNEW(char,namelen+dim);
- memcpy(namebuf+dim,element->name->text,namelen);
- namelen += dim;
- }
- else {
- /* the element is a non-array class */
- namebuf = DMNEW(char,namelen+2+dim);
- namebuf[dim] = 'L';
- memcpy(namebuf+dim+1,element->name->text,namelen);
- namelen += (2+dim);
- namebuf[namelen-1] = ';';
- }
- memset(namebuf,'[',dim);
-
- return class_new( utf_new(namebuf,namelen) );
-}
-
-/************************** function: utf_strlen ******************************
-
- determine number of unicode characters in the utf string
-
-*******************************************************************************/
-
-u4 utf_strlen(utf *u)
-{
- char *endpos = utf_end(u); /* points behind utf string */
- char *utf_ptr = u->text; /* current position in utf text */
- u4 len = 0; /* number of unicode characters */
-
- while (utf_ptr<endpos) {
- len++;
- /* next unicode character */
- utf_nextu2(&utf_ptr);
- }
-
- if (utf_ptr!=endpos)
- /* string ended abruptly */
- panic("illegal utf string");
-
- return len;
-}
-
-