static void _check_final_method_conflict(Klass* klass, uint32_t method_id) { Method* prev_meth = _search_own_method(klass, method_id); if (prev_meth) { if (METHOD_IS_FINAL(prev_meth)) { assert(false); // TODO raise error } } }
static Klass* _klass_new(uint32_t klass_id, Val name, uint32_t parent_id) { Klass* k = val_alloc(KLASS_KLASS, sizeof(Klass)); k->id = klass_id; k->name = name; k->parent_id = parent_id; IdMethods.init(&k->id_methods); Includes.init(&k->includes, 0); IdFieldIndexes.init(&k->id_field_indexes); Fields.init(&k->fields, 0); k->hash_func = NULL; k->eq_func = NULL; k->destruct_func = NULL; k->delete_func = NULL; k->debug_func = NULL; val_perm(k); ConstSearchKey key = {.parent = k->parent_id, .name_str = VAL_TO_STR(k->name)}; KlassSearchMap.insert(&runtime.klass_search_map, key, k->id); ConstSearchMap.insert(&runtime.const_search_map, key, (Val)k); return k; } static void _klass_delete(Klass* k) { ConstSearchKey key = {.parent = k->parent_id, .name_str = VAL_TO_STR(k->name)}; KlassSearchMap.remove(&runtime.klass_search_map, key); ConstSearchMap.remove(&runtime.const_search_map, key); IdMethods.cleanup(&k->id_methods); Includes.cleanup(&k->includes); IdFieldIndexes.cleanup(&k->id_field_indexes); Fields.cleanup(&k->fields); val_free(k); } static Method* _method_new(uint32_t method_id, int32_t min_argc, int32_t max_argc, bool is_final) { Method* meth = val_alloc(KLASS_METHOD, sizeof(Method)); METHOD_ID(meth) = method_id; METHOD_IS_FINAL(meth) = is_final; METHOD_MIN_ARGC(meth) = min_argc; METHOD_MAX_ARGC(meth) = max_argc; val_perm(meth); return meth; }
static jboolean addProxyMethods(Env* env, Class* proxyClass, Class* clazz, ProxyClassData* proxyClassData) { // Add constructors from the super class and override all overridable methods. Constructors will use // the same impl as the superclass. Overridden methods will have _rvmProxy0 as its impl. if (clazz->superclass) { if (!addProxyMethods(env, proxyClass, clazz->superclass, proxyClassData)) return FALSE; } Method* method = rvmGetMethods(env, clazz); if (rvmExceptionOccurred(env)) return FALSE; for (; method != NULL; method = method->next) { if (!METHOD_IS_STATIC(method) && !METHOD_IS_PRIVATE(method) && !METHOD_IS_FINAL(method) && (!METHOD_IS_CONSTRUCTOR(method) || clazz == proxyClass->superclass)) { void* impl = NULL; jint access = (method->access & (~ACC_ABSTRACT & ~ACC_NATIVE)) | ACC_FINAL; if (METHOD_IS_CONSTRUCTOR(method)) { impl = method->impl; // TODO: For now we make all constructors public to satisfy java.lang.reflect.Proxy. access = ACC_PUBLIC; if (!addProxyMethod(env, proxyClass, method, access, impl)) return FALSE; } else { impl = _proxy0; if (METHOD_IS_PUBLIC(method)) { ProxyMethod* proxyMethod = hasMethod(env, proxyClass, method->name, method->desc); if (rvmExceptionOccurred(env)) return FALSE; if (!proxyMethod) { proxyMethod = addProxyMethod(env, proxyClass, method, access, impl); if (!proxyMethod) return FALSE; } // Record the lookup function in proxyClassData LookupEntry* entry = rvmAllocateMemory(env, sizeof(LookupEntry)); if (!entry) return FALSE; entry->key.name = method->name; entry->key.desc = method->desc; entry->method = proxyMethod; HASH_ADD(hh, proxyClassData->lookupsHash, key, sizeof(LookupKey), entry); } } } } return TRUE; }