void Java_java_lang_Class_newInstance(void) { INSTANCE_CLASS currentClass = getFP()->thisMethod->ofClass; CLASS clazz = topStackAsType(CLASS); if (IS_ARRAY_CLASS(clazz) || ((clazz->accessFlags & (ACC_INTERFACE | ACC_ABSTRACT)) != 0)) { raiseException("java/lang/InstantiationException"); return; } if (classHasAccessToClass(currentClass, clazz)) { METHOD method = lookupMethod(clazz, initNameAndType, currentClass); if ( (method != NULL) && (method->ofClass == (INSTANCE_CLASS)clazz) /* I don't understand why, but we're not allowed access to * a protected <init> method of a superclass. */ && classHasAccessToMember(currentClass, (method->accessFlags & ~ACC_PROTECTED), (INSTANCE_CLASS)clazz, (INSTANCE_CLASS)clazz) ) { START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(INSTANCE, object, instantiate((INSTANCE_CLASS)clazz)); if (object != NULL) { /* Put the result back on the stack */ topStackAsType(INSTANCE) = object; /* Will get the result */ /* We now need to call the initializer. We'd like to just * push a second copy of the object onto the stack, and then * do pushFrame(method). But we can't, because that would * not necessarily coincide with the stack map of the * current method. */ pushFrame(RunCustomCodeMethod); pushStackAsType(CustomCodeCallbackFunction, newInstanceReturnObject); pushStackAsType(INSTANCE, object); /* pushFrame may signal a stack overflow. */ pushFrame(method); } else { /* We will already have thrown an appropriate error */ } END_TEMPORARY_ROOTS return; } }
void Java_java_lang_Class_forName(void) { START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(STRING_INSTANCE, string, topStackAsType(STRING_INSTANCE)); if (string == NULL) { raiseException(NullPointerException); } else { long length = string->length; CLASS thisClass = NULL; DECLARE_TEMPORARY_ROOT(char*, className, mallocBytes(length + 1)); getStringContentsSafely(string, className, length + 1); if (strchr(className, '/') == NULL) { replaceLetters(className,'.','/'); if (verifyName(className, LegalClass, FALSE)) { thisClass = getClassX((CONST_CHAR_HANDLE)&className, 0, length); /* The specification does not require that the current * class have "access" to thisClass */ } } if (thisClass != NULL) { topStackAsType(CLASS) = thisClass; if (!IS_ARRAY_CLASS(thisClass)) { if (!CLASS_INITIALIZED((INSTANCE_CLASS)thisClass)) { initializeClass((INSTANCE_CLASS)thisClass); } } } else { raiseExceptionMsg("java/lang/ClassNotFoundException", string); } } END_TEMPORARY_ROOTS }
/* Update a class and all the stuff hanging off it */ void* updateClass(void *object) { CLASS clazz = object; CLASS next = clazz->next; bool_t isArray = IS_ARRAY_CLASS(clazz); int length, i; UPDATE(clazz->ofClass); UPDATE(clazz->monitor); UPDATE(clazz->packageName); UPDATE(clazz->baseName); UPDATE(clazz->next); UPDATE(clazz->accessFlags); UPDATE(clazz->key); if (!isArray) { INSTANCE_CLASS iclazz = (INSTANCE_CLASS)clazz; CONSTANTPOOL constPool = iclazz->constPool; FIELDTABLE fieldTable = iclazz->fieldTable; METHODTABLE methodTable = iclazz->methodTable; unsigned short* ifaceTable = iclazz->ifaceTable; POINTERLIST staticFields = iclazz->staticFields; UPDATE(iclazz->superClass); UPDATE(iclazz->constPool); UPDATE(iclazz->fieldTable); UPDATE(iclazz->methodTable); UPDATE(iclazz->ifaceTable); UPDATE(iclazz->staticFields); UPDATE(iclazz->instSize); UPDATE(iclazz->status); UPDATE(iclazz->initThread); /* Update the constant pool. All entries in the constant pool, * except for CONSTANT_NameAndType, are 4-byte entries. The * ROMized image shouldn't have any of those. */ if (constPool != NULL) { /* unsigned char *tags = CONSTANTPOOL_TAGS(constPool); */ length = CONSTANTPOOL_LENGTH(constPool); for (i = 0; i < length; i++) { UPDATE(constPool->entries[i].integer); } } /* Update the fields */ if (fieldTable != NULL) { updateFieldTable(fieldTable); } /* Update the methods */ if (methodTable != NULL) { updateMethodTable(methodTable); } /* Update the interface table */ if (ifaceTable != NULL) { length = ifaceTable[0]; for (i = 0; i <= length; i++) { UPDATE(ifaceTable[i]); } } /* In the ROMized image, static Fields should always be NULL */ if (staticFields != NULL) { fprintf(stderr, "Non null static fields\n"); } } else { /* An array class is much simpler */ ARRAY_CLASS aclazz = (ARRAY_CLASS)clazz; int gcType = aclazz->gcType; if (gcType == GCT_ARRAY) { UPDATE(aclazz->u.primType); } else { UPDATE(aclazz->u.elemClass); } UPDATE(aclazz->itemSize); UPDATE(aclazz->gcType); } return next; }