Пример #1
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(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);
  }
}
Пример #2
0
static LLVMValueRef dispatch_function(compile_t* c, ast_t* from, gentype_t* g,
  LLVMValueRef l_value, const char* method_name, ast_t* typeargs)
{
  LLVMValueRef func;

  if(g->use_type == c->object_ptr)
  {
    // Virtual, get the function by selector colour.
    uint32_t index = genfun_vtable_index(c, g, method_name, typeargs);
    assert(index != (uint32_t)-1);

    // Get the function from the vtable.
    func = gendesc_vtable(c, l_value, index);

    // Cast to the right function type.
    LLVMTypeRef f_type = genfun_sig(c, g, method_name, typeargs);

    if(f_type == NULL)
    {
      ast_error(from, "couldn't create a signature for '%s'", method_name);
      return NULL;
    }

    f_type = LLVMPointerType(f_type, 0);
    func = LLVMBuildBitCast(c->builder, func, f_type, "method");
  } else {
    // Static, get the actual function.
    func = genfun_proto(c, g, method_name, typeargs);

    if(func == NULL)
    {
      ast_error(from, "couldn't locate '%s'", method_name);
      return NULL;
    }
  }

  return func;
}