Пример #1
0
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
    }
  }
}
Пример #2
0
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;
}
Пример #3
0
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;
}