static Class* createClass(Env* env, ClassInfoHeader* header, ClassLoader* classLoader) { ClassInfo ci; void* p = header; readClassInfo(&p, &ci); Class* superclass = NULL; if (ci.superclassName) { superclass = rvmFindClassUsingLoader(env, ci.superclassName, classLoader); if (!superclass) return NULL; } rvmObtainClassLock(env); Class* clazz = rvmAllocateClass(env, header->className, superclass, classLoader, ci.access, header->typeInfo, header->vitable, header->itables, header->classDataSize, header->instanceDataSize, header->instanceDataOffset, header->classRefCount, header->instanceRefCount, ci.attributes, header->initializer); if (clazz) { if (!rvmRegisterClass(env, clazz)) { rvmReleaseClassLock(env); return NULL; } header->clazz = clazz; rvmHookClassLoaded(env, clazz, (void*)header); } rvmReleaseClassLock(env); return clazz; }
Class* rvmProxyCreateProxyClass(Env* env, Class* superclass, ClassLoader* classLoader, char* className, jint interfacesCount, Class** interfaces, jint instanceDataSize, jint instanceDataOffset, unsigned short instanceRefCount, ProxyHandler handler) { // Allocate the proxy class. Class* proxyClass = rvmAllocateClass(env, className, superclass, classLoader, CLASS_TYPE_PROXY | ACC_PUBLIC | ACC_FINAL, offsetof(Class, data) + sizeof(ProxyClassData), instanceDataSize, instanceDataOffset, 1, instanceRefCount, NULL, NULL); if (!proxyClass) return NULL; ProxyClassData* proxyClassData = (ProxyClassData*) proxyClass->data; proxyClassData->handler = handler; // Add interfaces jint i; for (i = 0; i < interfacesCount; i++) { if (!rvmAddInterface(env, proxyClass, (Class*) interfaces[i])) return NULL; } // Initialize methods to NULL to prevent rvmGetMethods() from trying to load the methods if called with this proxy class proxyClass->_methods = NULL; Class* c = proxyClass; while (c) { Interface* interface = rvmGetInterfaces(env, c); if (rvmExceptionCheck(env)) return NULL; if (!implementAbstractInterfaceMethods(env, proxyClass, interface, proxyClassData)) return NULL; c = c->superclass; } if (!addProxyMethods(env, proxyClass, superclass, proxyClassData)) return NULL; if (!rvmRegisterClass(env, proxyClass)) return NULL; return proxyClass; }
static Class* createArrayClass(Env* env, Class* componentType) { jint length = strlen(componentType->name); char* desc = NULL; if (CLASS_IS_ARRAY(componentType) || CLASS_IS_PRIMITIVE(componentType)) { desc = rvmAllocateMemoryAtomic(env, length + 2); if (!desc) return NULL; desc[0] = '['; strcat(desc, componentType->name); } else { desc = rvmAllocateMemoryAtomic(env, length + 4); if (!desc) return NULL; desc[0] = '['; desc[1] = 'L'; strcat(desc, componentType->name); desc[length + 2] = ';'; } // TODO: Add clone() method. Class* clazz = rvmAllocateClass(env, desc, java_lang_Object, componentType->classLoader, CLASS_TYPE_ARRAY | CLASS_STATE_INITIALIZED | ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT, sizeof(Class), sizeof(Object), sizeof(Object), 0, 0, NULL, NULL); if (!clazz) return NULL; clazz->componentType = componentType; // Initialize methods to NULL to prevent rvmGetMethods() from trying to load the methods if called with this array class clazz->_methods = NULL; if (!rvmAddInterface(env, clazz, java_lang_Cloneable)) return NULL; if (!rvmAddInterface(env, clazz, java_io_Serializable)) return NULL; if (!rvmRegisterClass(env, clazz)) return NULL; return clazz; }
static Class* createPrimitiveClass(Env* env, const char* desc) { Class* clazz = rvmAllocateClass(env, desc, NULL, NULL, CLASS_TYPE_PRIMITIVE | CLASS_STATE_INITIALIZED | ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT, sizeof(Class), sizeof(Object), sizeof(Object), 0, 0, NULL, NULL); if (!clazz) return NULL; clazz->_interfaces = NULL; clazz->_fields = NULL; clazz->_methods = NULL; return clazz; }
static Class* createClass(Env* env, ClassInfoHeader* header, ClassLoader* classLoader) { ClassInfo ci; void* p = header; readClassInfo(&p, &ci); Class* superclass = NULL; if (ci.superclassName) { superclass = rvmFindClassUsingLoader(env, ci.superclassName, classLoader); if (!superclass) return NULL; } Class* clazz = rvmAllocateClass(env, header->className, superclass, classLoader, ci.access, header->classDataSize, header->instanceDataSize, header->instanceDataOffset, header->classRefCount, header->instanceRefCount, ci.attributes, header->initializer); if (clazz) { if (!rvmRegisterClass(env, clazz)) return NULL; header->clazz = clazz; } return clazz; }