Ejemplo n.º 1
0
Archivo: reach.c Proyecto: DevL/ponyc
void reach_dump(reachable_types_t* r)
{
  printf("REACH\n");

  size_t i = HASHMAP_BEGIN;
  reachable_type_t* t;

  while((t = reachable_types_next(r, &i)) != NULL)
  {
    printf("  %s vtable size %d\n", t->name, t->vtable_size);
    size_t j = HASHMAP_BEGIN;
    reachable_method_name_t* m;

    while((m = reachable_method_names_next(&t->methods, &j)) != NULL)
    {
      size_t k = HASHMAP_BEGIN;
      reachable_method_t* p;

      while((p = reachable_methods_next(&m->r_methods, &k)) != NULL)
      {
        printf("    %s vtable index %d (%p)\n", p->name, p->vtable_index, p);
      }
    }
  }
}
Ejemplo n.º 2
0
bool genfun_method_bodies(compile_t* c, reachable_type_t* t)
{
  switch(t->underlying)
  {
    case TK_PRIMITIVE:
    case TK_STRUCT:
    case TK_CLASS:
    case TK_ACTOR:
      break;

    default:
      return true;
  }

  size_t i = HASHMAP_BEGIN;
  reachable_method_name_t* n;

  while((n = reachable_method_names_next(&t->methods, &i)) != NULL)
  {
    size_t j = HASHMAP_BEGIN;
    reachable_method_t* m;

    while((m = reachable_methods_next(&n->r_methods, &j)) != NULL)
    {
      if(m->intrinsic)
        continue;

      switch(ast_id(m->r_fun))
      {
        case TK_NEW:
          if(t->underlying == TK_ACTOR)
          {
            if(!genfun_newbe(c, t, m))
              return false;
          } else {
            if(!genfun_new(c, t, m))
              return false;
          }
          break;

        case TK_BE:
          if(!genfun_be(c, t, m))
            return false;
          break;

        case TK_FUN:
          if(!genfun_fun(c, t, m))
            return false;
          break;

        default:
          assert(0);
          return false;
      }
    }
  }

  return true;
}
Ejemplo n.º 3
0
static LLVMValueRef make_vtable(compile_t* c, gentype_t* g)
{
  uint32_t vtable_size = genfun_vtable_size(c, g);

  if(vtable_size == 0)
    return LLVMConstArray(c->void_ptr, NULL, 0);

  size_t buf_size = vtable_size * sizeof(LLVMValueRef);
  LLVMValueRef* vtable = (LLVMValueRef*)pool_alloc_size(buf_size);
  memset(vtable, 0, buf_size);

  reachable_type_t* t = reach_type(c->reachable, g->type_name);

  size_t i = HASHMAP_BEGIN;
  reachable_method_name_t* n;

  while((n = reachable_method_names_next(&t->methods, &i)) != NULL)
  {
    size_t j = HASHMAP_BEGIN;
    reachable_method_t* m;

    while((m = reachable_methods_next(&n->r_methods, &j)) != NULL)
    {
      const char* fullname = genname_fun(t->name, n->name, m->typeargs);
      token_id t = ast_id(m->r_fun);

      switch(t)
      {
        case TK_NEW:
        case TK_BE:
          if(g->underlying == TK_ACTOR)
            fullname = genname_be(fullname);
          break;

        default: {}
      }

      uint32_t index = m->vtable_index;
      assert(index != (uint32_t)-1);
      assert(vtable[index] == NULL);

      if(g->primitive != NULL)
        vtable[index] = make_unbox_function(c, g, fullname, t);
      else
        vtable[index] = make_function_ptr(c, fullname, c->void_ptr);
    }
  }

  for(uint32_t i = 0; i < vtable_size; i++)
  {
    if(vtable[i] == NULL)
      vtable[i] = LLVMConstNull(c->void_ptr);
  }

  LLVMValueRef r = LLVMConstArray(c->void_ptr, vtable, vtable_size);
  pool_free_size(buf_size, vtable);
  return r;
}
Ejemplo n.º 4
0
Archivo: reach.c Proyecto: DevL/ponyc
size_t reach_method_count(reachable_type_t* t)
{
  size_t i = HASHMAP_BEGIN;
  reachable_method_name_t* n;
  size_t count = 0;

  while((n = reachable_method_names_next(&t->methods, &i)) != NULL)
    count += reachable_methods_size(&n->r_methods);

  return count;
}
Ejemplo n.º 5
0
static void print_methods(compile_t* c, reachable_type_t* t, printbuf_t* buf)
{
  size_t i = HASHMAP_BEGIN;
  reachable_method_name_t* n;

  while((n = reachable_method_names_next(&t->methods, &i)) != NULL)
  {
    size_t j = HASHMAP_BEGIN;
    reachable_method_t* m;

    while((m = reachable_methods_next(&n->r_methods, &j)) != NULL)
      print_method(c, buf, t, n->name, m->typeargs);
  }
}
Ejemplo n.º 6
0
Archivo: reach.c Proyecto: DevL/ponyc
static void add_methods_to_type(reachable_method_stack_t** s,
  reachable_type_t* from, reachable_type_t* to)
{
  size_t i = HASHMAP_BEGIN;
  reachable_method_name_t* n;

  while((n = reachable_method_names_next(&from->methods, &i)) != NULL)
  {
    size_t j = HASHMAP_BEGIN;
    reachable_method_t* m;

    while((m = reachable_methods_next(&n->r_methods, &j)) != NULL)
      add_method(s, to, n->name, m->typeargs);
  }
}
Ejemplo n.º 7
0
Archivo: genfun.c Proyecto: fydot/ponyc
bool genfun_methods(compile_t* c, gentype_t* g)
{
  reachable_type_t* t = reach_type(c->reachable, g->type_name);

  size_t i = HASHMAP_BEGIN;
  reachable_method_name_t* n;

  while((n = reachable_method_names_next(&t->methods, &i)) != NULL)
  {
    size_t j = HASHMAP_BEGIN;
    reachable_method_t* m;
    LLVMValueRef fun;

    while((m = reachable_methods_next(&n->r_methods, &j)) != NULL)
    {
      switch(ast_id(m->r_fun))
      {
        case TK_NEW:
          if(g->underlying == TK_ACTOR)
            fun = genfun_newbe(c, g, n->name, m->typeargs);
          else
            fun = genfun_new(c, g, n->name, m->typeargs);
          break;

        case TK_BE:
          fun = genfun_be(c, g, n->name, m->typeargs);
          break;

        case TK_FUN:
          fun = genfun_fun(c, g, n->name, m->typeargs);
          break;

        default:
          fun = NULL;
          break;
      }

      if(fun == NULL)
        return false;
    }
  }

  if(!genfun_allocator(c, g))
    return false;

  return true;
}
Ejemplo n.º 8
0
Archivo: paint.c Proyecto: DevL/ponyc
// Step 1
static void find_names_types_use(painter_t* painter, reachable_types_t* types)
{
  assert(painter != NULL);
  assert(types != NULL);

  size_t i = HASHMAP_BEGIN;
  size_t typemap_index = 0;
  uint64_t typemap_mask = 1;
  reachable_type_t* type;

  while((type = reachable_types_next(types, &i)) != NULL)
  {
    assert(typemap_index < painter->typemap_size);
    size_t j = HASHMAP_BEGIN;
    reachable_method_name_t* mn;

    while((mn = reachable_method_names_next(&type->methods, &j)) != NULL)
    {
      size_t k = HASHMAP_BEGIN;
      reachable_method_t* method;

      while((method = reachable_methods_next(&mn->r_methods, &k)) != NULL)
      {
        const char* name = method->name;

        name_record_t* name_rec = find_name(painter, name);

        if(name_rec == NULL)  // This is the first use of this name
          name_rec = add_name(painter, name);

        // Mark this name as using the current type
        name_rec->type_map[typemap_index] |= typemap_mask;
      }
    }

    // Advance to next type bitmap entry
    typemap_mask <<= 1;

    if(typemap_mask == 0)
    {
      typemap_mask = 1;
      typemap_index++;
    }
  }
}
Ejemplo n.º 9
0
Archivo: paint.c Proyecto: DevL/ponyc
// Step 5
static void distribute_info(painter_t* painter, reachable_types_t* types)
{
  assert(painter != NULL);
  assert(types != NULL);

  size_t i = HASHMAP_BEGIN;
  reachable_type_t* type;

  // Iterate over all types
  while((type = reachable_types_next(types, &i)) != NULL)
  {
    if(reachable_method_names_size(&type->methods) == 0)
      continue;

    size_t j = HASHMAP_BEGIN;
    reachable_method_name_t* mn;
    uint32_t max_colour = 0;

    // Iterate over all method names in type
    while((mn = reachable_method_names_next(&type->methods, &j)) != NULL)
    {
      size_t k = HASHMAP_BEGIN;
      reachable_method_t* method;

      while((method = reachable_methods_next(&mn->r_methods, &k)) != NULL)
      {
        // Store colour assigned to name in reachable types set
        const char* name = method->name;

        name_record_t* name_rec = find_name(painter, name);
        assert(name_rec != NULL);

        uint32_t colour = name_rec->colour;
        method->vtable_index = colour;

        if(colour > max_colour)
          max_colour = colour;
      }
    }

    // Store vtable size for type
    type->vtable_size = max_colour + 1;
  }
}
Ejemplo n.º 10
0
bool genfun_method_sigs(compile_t* c, reachable_type_t* t)
{
  size_t i = HASHMAP_BEGIN;
  reachable_method_name_t* n;

  while((n = reachable_method_names_next(&t->methods, &i)) != NULL)
  {
    size_t j = HASHMAP_BEGIN;
    reachable_method_t* m;

    while((m = reachable_methods_next(&n->r_methods, &j)) != NULL)
      make_prototype(c, t, m);
  }

  if(!genfun_allocator(c, t))
    return false;

  return true;
}