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; }
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 void loadInterfaces(Env* env, Class* clazz) { ClassInfoHeader* header = lookupClassInfo(env, clazz->name, !clazz->classLoader || !clazz->classLoader->parent ? _bcBootClassesHash : _bcClassesHash); if (!header) return; ClassInfo ci; jint i; void* p = header; readClassInfo(&p, &ci); for (i = 0; i < ci.interfaceCount; i++) { const char* interfaceName = readInterfaceName(&p); Class* interface = rvmFindClassUsingLoader(env, interfaceName, clazz->classLoader); if (!interface) return; rvmAddInterface(env, clazz, interface); if (rvmExceptionCheck(env)) return; } }