Пример #1
0
Файл: reach.c Проект: DevL/ponyc
static void add_method(reachable_method_stack_t** s,
  reachable_type_t* t, const char* name, ast_t* typeargs)
{
  reachable_method_name_t* n = reach_method_name(t, name);

  if(n == NULL)
  {
    n = POOL_ALLOC(reachable_method_name_t);
    n->name = name;
    reachable_methods_init(&n->r_methods, 0);
    reachable_method_names_put(&t->methods, n);
  }

  add_rmethod(s, t, n, typeargs);

  // Add to subtypes if we're an interface or trait.
  ast_t* def = (ast_t*)ast_data(t->type);

  switch(ast_id(def))
  {
    case TK_INTERFACE:
    case TK_TRAIT:
    {
      size_t i = HASHMAP_BEGIN;
      reachable_type_t* t2;

      while((t2 = reachable_type_cache_next(&t->subtypes, &i)) != NULL)
        add_method(s, t2, name, typeargs);

      break;
    }

    default: {}
  }
}
Пример #2
0
static void add_rmethod_to_subtype(reach_t* r, reach_type_t* t,
  reach_method_name_t* n, reach_method_t* m, pass_opt_t* opt)
{
  // Add the method to the type if it isn't already there.
  reach_method_name_t* n2 = add_method_name(t, n->name);
  add_rmethod(r, t, n2, m->cap, m->typeargs, opt);

  // Add this mangling to the type if it isn't already there.
  reach_method_t* mangled = reach_mangled_get(&n2->r_mangled, m);

  if(mangled != NULL)
    return;

  mangled = POOL_ALLOC(reach_method_t);
  memset(mangled, 0, sizeof(reach_method_t));

  mangled->name = m->name;
  mangled->mangled_name = m->mangled_name;
  mangled->full_name = make_full_name(t, mangled);

  mangled->cap = m->cap;
  mangled->r_fun = ast_dup(m->r_fun);
  mangled->typeargs = ast_dup(m->typeargs);
  mangled->forwarding = true;

  mangled->param_count = m->param_count;
  mangled->params = (reach_param_t*)ponyint_pool_alloc_size(
    mangled->param_count * sizeof(reach_param_t));
  memcpy(mangled->params, m->params, m->param_count * sizeof(reach_param_t));
  mangled->result = m->result;

  // Add to the mangled table only.
  reach_mangled_put(&n2->r_mangled, mangled);
}
Пример #3
0
static void reachable_method(reach_t* r, ast_t* type, const char* name,
  ast_t* typeargs, pass_opt_t* opt)
{
  reach_type_t* t = add_type(r, type, opt);
  reach_method_name_t* n = add_method_name(t, name);
  reach_method_t* m = add_rmethod(r, t, n, n->cap, typeargs, opt);

  if((n->id == TK_FUN) && ((n->cap == TK_BOX) || (n->cap == TK_TAG)))
  {
    // TODO: if it doesn't use this-> in a constructor, we could reuse the
    // function, which means always reuse in a fun tag
    bool subordinate = (n->cap == TK_TAG);
    reach_method_t* m2;

    if(t->underlying != TK_PRIMITIVE)
    {
      m2 = add_rmethod(r, t, n, TK_REF, typeargs, opt);

      if(subordinate)
      {
        m2->intrinsic = true;
        m->subordinate = m2;
        m = m2;
      }
    }

    m2 = add_rmethod(r, t, n, TK_VAL, typeargs, opt);

    if(subordinate)
    {
      m2->intrinsic = true;
      m->subordinate = m2;
      m = m2;
    }

    if(n->cap == TK_TAG)
    {
      m2 = add_rmethod(r, t, n, TK_BOX, typeargs, opt);
      m2->intrinsic = true;
      m->subordinate = m2;
      m = m2;
    }
  }
}