Exemplo n.º 1
0
Arquivo: reach.c Projeto: 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);
      }
    }
  }
}
Exemplo n.º 2
0
static void print_types(compile_t* c, FILE* fp, printbuf_t* buf)
{
  size_t i = HASHMAP_BEGIN;
  reachable_type_t* t;

  while((t = reachable_types_next(c->reachable, &i)) != NULL)
  {
    // Print the docstring if we have one.
    ast_t* def = (ast_t*)ast_data(t->ast);
    ast_t* docstring = ast_childidx(def, 6);

    if(ast_id(docstring) == TK_STRING)
      fprintf(fp, "/*\n%s*/\n", ast_name(docstring));

    if(!is_pointer(t->ast) && !is_maybe(t->ast) && !is_machine_word(t->ast))
    {
      // Forward declare an opaque type.
      fprintf(fp, "typedef struct %s %s;\n\n", t->name, t->name);

      // Function signature for the allocator.
      printbuf(buf,
        "/* Allocate a %s without initialising it. */\n%s* %s_Alloc();\n\n",
        t->name,
        t->name,
        t->name
        );
    }

    print_methods(c, t, buf);
  }
}
Exemplo n.º 3
0
static bool need_primitive_call(compile_t* c, const char* method)
{
  size_t i = HASHMAP_BEGIN;
  reachable_type_t* t;

  while((t = reachable_types_next(c->reachable, &i)) != NULL)
  {
    if(ast_id(t->type) == TK_TUPLETYPE)
      continue;

    ast_t* def = (ast_t*)ast_data(t->type);

    if(ast_id(def) != TK_PRIMITIVE)
      continue;

    reachable_method_name_t* n = reach_method_name(t, method);

    if(n == NULL)
      continue;

    return true;
  }

  return false;
}
Exemplo n.º 4
0
Arquivo: reach.c Projeto: DevL/ponyc
static void add_traits_to_type(reachable_method_stack_t** s,
  reachable_types_t* r, reachable_type_t* t)
{
  size_t i = HASHMAP_BEGIN;
  reachable_type_t* t2;

  while((t2 = reachable_types_next(r, &i)) != NULL)
  {
    if(ast_id(t2->type) == TK_TUPLETYPE)
      continue;

    ast_t* def = (ast_t*)ast_data(t2->type);

    switch(ast_id(def))
    {
      case TK_INTERFACE:
      case TK_TRAIT:
        if(is_subtype(t->type, t2->type, NULL))
        {
          reachable_type_cache_put(&t->subtypes, t2);
          reachable_type_cache_put(&t2->subtypes, t);
          add_methods_to_type(s, t2, t);
        }
        break;

      default: {}
    }
  }
}
Exemplo n.º 5
0
static void primitive_call(compile_t* c, const char* method, LLVMValueRef arg)
{
  size_t count = 1;

  if(arg != NULL)
    count++;

  size_t i = HASHMAP_BEGIN;
  reachable_type_t* t;

  while((t = reachable_types_next(c->reachable, &i)) != NULL)
  {
    if(t->underlying != TK_PRIMITIVE)
      continue;

    reachable_method_t* m = reach_method(t, method, NULL);

    if(m == NULL)
      continue;

    LLVMValueRef args[2];
    args[0] = t->instance;
    args[1] = arg;

    codegen_call(c, m->func, args, count);
  }
}
Exemplo n.º 6
0
Arquivo: paint.c Projeto: 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++;
    }
  }
}
Exemplo n.º 7
0
Arquivo: paint.c Projeto: 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;
  }
}
Exemplo n.º 8
0
Arquivo: genexe.c Projeto: volth/ponyc
static void primitive_call(compile_t* c, const char* method, LLVMValueRef arg)
{
  size_t count = 1;

  if(arg != NULL)
    count++;

  size_t i = HASHMAP_BEGIN;
  reachable_type_t* t;

  while((t = reachable_types_next(c->reachable, &i)) != NULL)
  {
    if(ast_id(t->type) == TK_TUPLETYPE)
      continue;

    ast_t* def = (ast_t*)ast_data(t->type);

    if(ast_id(def) != TK_PRIMITIVE)
      continue;

    reachable_method_name_t* n = reach_method_name(t, method);

    if(n == NULL)
      continue;

    gentype_t g;

    if(!gentype(c, t->type, &g))
    {
      assert(0);
      return;
    }

    LLVMValueRef fun = genfun_proto(c, &g, method, NULL);
    assert(fun != NULL);

    LLVMValueRef args[2];
    args[0] = g.instance;
    args[1] = arg;

    codegen_call(c, fun, args, count);
  }
}
Exemplo n.º 9
0
static bool need_primitive_call(compile_t* c, const char* method)
{
  size_t i = HASHMAP_BEGIN;
  reachable_type_t* t;

  while((t = reachable_types_next(c->reachable, &i)) != NULL)
  {
    if(t->underlying != TK_TUPLETYPE)
      continue;

    reachable_method_name_t* n = reach_method_name(t, method);

    if(n == NULL)
      continue;

    return true;
  }

  return false;
}
Exemplo n.º 10
0
Arquivo: reach.c Projeto: DevL/ponyc
static void add_types_to_trait(reachable_method_stack_t** s,
  reachable_types_t* r, reachable_type_t* t)
{
  size_t i = HASHMAP_BEGIN;
  reachable_type_t* t2;

  ast_t* def = (ast_t*)ast_data(t->type);
  bool interface = ast_id(def) == TK_INTERFACE;

  while((t2 = reachable_types_next(r, &i)) != NULL)
  {
    if(ast_id(t2->type) == TK_TUPLETYPE)
      continue;

    ast_t* def2 = (ast_t*)ast_data(t2->type);

    switch(ast_id(def2))
    {
      case TK_INTERFACE:
      {
        // Use the same typeid.
        if(interface && is_eqtype(t->type, t2->type, NULL))
          t->type_id = t2->type_id;
        break;
      }

      case TK_PRIMITIVE:
      case TK_CLASS:
      case TK_ACTOR:
        if(is_subtype(t2->type, t->type, NULL))
        {
          reachable_type_cache_put(&t->subtypes, t2);
          reachable_type_cache_put(&t2->subtypes, t);
          add_methods_to_type(s, t, t2);
        }
        break;

      default: {}
    }
  }
}
Exemplo n.º 11
0
bool gentypes(compile_t* c)
{
  reachable_type_t* t;
  size_t i;

  genprim_builtins(c);

  PONY_LOG(c->opt, VERBOSITY_INFO, (" Data prototypes\n"));
  i = HASHMAP_BEGIN;

  while((t = reachable_types_next(&c->reachable->types, &i)) != NULL)
  {
    if(!make_opaque_struct(c, t))
      return false;

    gendesc_type(c, t);
    make_debug_info(c, t);
    make_box_type(c, t);
    make_dispatch(c, t);
    gentrace_prototype(c, t);
  }

  PONY_LOG(c->opt, VERBOSITY_INFO, (" Data types\n"));
  i = HASHMAP_BEGIN;

  while((t = reachable_types_next(&c->reachable->types, &i)) != NULL)
  {
    if(!make_struct(c, t))
      return false;

    make_global_instance(c, t);
  }

  PONY_LOG(c->opt, VERBOSITY_INFO, (" Function prototypes\n"));
  i = HASHMAP_BEGIN;

  while((t = reachable_types_next(&c->reachable->types, &i)) != NULL)
  {
    make_debug_final(c, t);
    make_pointer_methods(c, t);

    if(!genfun_method_sigs(c, t))
      return false;
  }

  PONY_LOG(c->opt, VERBOSITY_INFO, (" Functions\n"));
  i = HASHMAP_BEGIN;

  while((t = reachable_types_next(&c->reachable->types, &i)) != NULL)
  {
    if(!genfun_method_bodies(c, t))
      return false;
  }

  PONY_LOG(c->opt, VERBOSITY_INFO, (" Descriptors\n"));
  i = HASHMAP_BEGIN;

  while((t = reachable_types_next(&c->reachable->types, &i)) != NULL)
  {
    if(!make_trace(c, t))
      return false;

    gendesc_init(c, t);
  }

  return true;
}