Пример #1
0
void gentrace(compile_t* c, LLVMValueRef ctx, LLVMValueRef value, ast_t* type)
{
  switch(trace_type(type))
  {
    case TRACE_NONE:
      assert(0);
      return;

    case TRACE_PRIMITIVE:
      return;

    case TRACE_MAYBE:
      trace_maybe(c, ctx, value, type);
      return;

    case TRACE_ACTOR:
      trace_actor(c, ctx, value);
      return;

    case TRACE_KNOWN_VAL:
      trace_known(c, ctx, value, type, true);
      return;

    case TRACE_UNKNOWN_VAL:
      trace_unknown(c, ctx, value, true);
      return;

    case TRACE_KNOWN:
      trace_known(c, ctx, value, type, false);
      return;

    case TRACE_UNKNOWN:
      trace_unknown(c, ctx, value, false);
      return;

    case TRACE_TAG:
      trace_tag(c, ctx, value);
      return;

    case TRACE_TAG_OR_ACTOR:
      trace_tag_or_actor(c, ctx, value);
      return;

    case TRACE_DYNAMIC:
    {
      LLVMBasicBlockRef next_block = codegen_block(c, "");
      trace_dynamic(c, ctx, value, type, type, NULL, next_block);
      LLVMBuildBr(c->builder, next_block);
      LLVMPositionBuilderAtEnd(c->builder, next_block);
      return;
    }

    case TRACE_TUPLE:
      trace_tuple(c, ctx, value, type);
      return;
  }
}
Пример #2
0
void gentrace(compile_t* c, LLVMValueRef ctx, LLVMValueRef value, ast_t* type)
{
  switch(trace_type(type))
  {
    case TRACE_NONE:
      assert(0);
      return;

    case TRACE_MACHINE_WORD:
    case TRACE_PRIMITIVE:
      return;

    case TRACE_MAYBE:
      trace_maybe(c, ctx, value, type);
      return;

    case TRACE_VAL_KNOWN:
      trace_known(c, ctx, value, type, PONY_TRACE_IMMUTABLE);
      return;

    case TRACE_VAL_UNKNOWN:
      trace_unknown(c, ctx, value, PONY_TRACE_IMMUTABLE);
      return;

    case TRACE_MUT_KNOWN:
      trace_known(c, ctx, value, type, PONY_TRACE_MUTABLE);
      return;

    case TRACE_MUT_UNKNOWN:
      trace_unknown(c, ctx, value, PONY_TRACE_MUTABLE);
      return;

    case TRACE_TAG_KNOWN:
      trace_known(c, ctx, value, type, PONY_TRACE_OPAQUE);
      return;

    case TRACE_TAG_UNKNOWN:
      trace_unknown(c, ctx, value, PONY_TRACE_OPAQUE);
      return;

    case TRACE_DYNAMIC:
    {
      LLVMBasicBlockRef next_block = codegen_block(c, "");
      trace_dynamic(c, ctx, value, type, type, NULL, next_block);
      LLVMBuildBr(c->builder, next_block);
      LLVMPositionBuilderAtEnd(c->builder, next_block);
      return;
    }

    case TRACE_TUPLE:
      trace_tuple(c, ctx, value, type);
      return;
  }
}
Пример #3
0
static void trace_dynamic(compile_t* c, LLVMValueRef ctx, LLVMValueRef object,
  ast_t* type, ast_t* orig, ast_t* tuple, LLVMBasicBlockRef next_block)
{
  switch(ast_id(type))
  {
    case TK_UNIONTYPE:
    case TK_ISECTTYPE:
      trace_dynamic_union_or_isect(c, ctx, object, type, orig, tuple,
        next_block);
      break;

    case TK_TUPLETYPE:
    {
      // This is a boxed tuple. Trace the box, then handle the elements.
      trace_unknown(c, ctx, object, PONY_TRACE_OPAQUE);

      LLVMValueRef desc = gendesc_fetch(c, object);
      LLVMValueRef ptr = gendesc_ptr_to_fields(c, object, desc);
      trace_dynamic_tuple(c, ctx, ptr, desc, type, orig, tuple);
      break;
    }

    case TK_NOMINAL:
      trace_dynamic_nominal(c, ctx, object, type, orig, tuple, next_block);
      break;

    default: {}
  }
}
Пример #4
0
static void trace_static(compile_t* c, LLVMValueRef ctx, LLVMValueRef object,
  ast_t* src_type, ast_t* dst_type)
{
  pony_assert(ast_id(src_type) == TK_NOMINAL);

  int mutability = trace_cap_nominal(c->opt, src_type, dst_type, NULL);
  pony_assert(mutability != -1);

  if(is_known(src_type))
    trace_known(c, ctx, object, src_type, mutability);
  else
    trace_unknown(c, ctx, object, mutability);
}
Пример #5
0
static void trace_dynamic_union_or_isect(compile_t* c, LLVMValueRef ctx,
  LLVMValueRef object, ast_t* type, ast_t* orig, ast_t* tuple,
  LLVMBasicBlockRef next_block)
{
  // Trace as every type. This results in maximal tracing. It also results in
  // all tuple elements eventually being maximally traced.
  for(ast_t* child = ast_child(type);
    child != NULL;
    child = ast_sibling(child))
  {
    trace_dynamic(c, ctx, object, child, orig, tuple, next_block);
  }

  // No type matched. This may be a boxed primitive: trace it here.
  trace_unknown(c, ctx, object, PONY_TRACE_OPAQUE);
}
Пример #6
0
static void trace_tuple(compile_t* c, LLVMValueRef ctx, LLVMValueRef src_value,
  LLVMValueRef dst_value, ast_t* src_type, ast_t* dst_type)
{
  int i = 0;

  // We're a tuple, determined statically.
  if(ast_id(dst_type) == TK_TUPLETYPE)
  {
    ast_t* src_child = ast_child(src_type);
    ast_t* dst_child = ast_child(dst_type);
    while((src_child != NULL) && (dst_child != NULL))
    {
      // Extract each element and trace it.
      LLVMValueRef elem = LLVMBuildExtractValue(c->builder, dst_value, i, "");
      gentrace(c, ctx, elem, elem, src_child, dst_child);
      i++;
      src_child = ast_sibling(src_child);
      dst_child = ast_sibling(dst_child);
    }
    pony_assert(src_child == NULL && dst_child == NULL);
  } else {
    // This is a boxed tuple. Trace the box, then handle the elements.
    trace_unknown(c, ctx, dst_value, PONY_TRACE_OPAQUE);

    // Extract the elements from the original unboxed tuple.
    pony_assert(LLVMGetTypeKind(LLVMTypeOf(src_value)) == LLVMStructTypeKind);

    ast_t* src_child = ast_child(src_type);
    while(src_child != NULL)
    {
      LLVMValueRef elem = LLVMBuildExtractValue(c->builder, src_value, i, "");
      gentrace(c, ctx, elem, elem, src_child, src_child);
      i++;
      src_child = ast_sibling(src_child);
    }
  }
}
Пример #7
0
bool gentrace(compile_t* c, LLVMValueRef ctx, LLVMValueRef value, ast_t* type)
{
  bool tag = trace_as_tag(c, value, type);

  switch(ast_id(type))
  {
    case TK_UNIONTYPE:
    case TK_ISECTTYPE:
    {
      if(tag)
        trace_tag_or_actor(c, ctx, value);
      else
        trace_unknown(c, ctx, value);

      return true;
    }

    case TK_TUPLETYPE:
      return trace_tuple(c, ctx, value, type);

    case TK_NOMINAL:
    {
      switch(ast_id((ast_t*)ast_data(type)))
      {
        case TK_INTERFACE:
        case TK_TRAIT:
          if(tag)
            trace_tag_or_actor(c, ctx, value);
          else
            trace_unknown(c, ctx, value);

          return true;

        case TK_PRIMITIVE:
          // Do nothing.
          return false;

        case TK_STRUCT:
        case TK_CLASS:
          if(tag)
          {
            if(is_maybe(type))
              trace_maybe(c, ctx, value, type, true);
            else
              trace_tag(c, ctx, value);

            return true;
          }

          if(is_maybe(type))
          {
            trace_maybe(c, ctx, value, type, false);
            return true;
          }

          return trace_known(c, ctx, value, type);

        case TK_ACTOR:
          trace_actor(c, ctx, value);
          return true;

        default: {}
      }
      break;
    }

    default: {}
  }

  assert(0);
  return false;
}
Пример #8
0
void gentrace(compile_t* c, LLVMValueRef ctx, LLVMValueRef src_value,
  LLVMValueRef dst_value, ast_t* src_type, ast_t* dst_type)
{
  trace_t trace_method = trace_type(src_type);
  if(src_type != dst_type)
  {
    trace_method = trace_type_dst_cap(trace_method, trace_type(dst_type),
      src_type);
  }

  switch(trace_method)
  {
    case TRACE_NONE:
      pony_assert(0);
      return;

    case TRACE_MACHINE_WORD:
    {
      bool boxed = true;
      if(ast_id(dst_type) == TK_NOMINAL)
      {
        ast_t* def = (ast_t*)ast_data(dst_type);
        if(ast_id(def) == TK_PRIMITIVE)
          boxed = false;
      }

      if(boxed)
        trace_known(c, ctx, dst_value, src_type, PONY_TRACE_IMMUTABLE);

      return;
    }

    case TRACE_PRIMITIVE:
      return;

    case TRACE_MAYBE:
      trace_maybe(c, ctx, dst_value, src_type);
      return;

    case TRACE_VAL_KNOWN:
      trace_known(c, ctx, dst_value, src_type, PONY_TRACE_IMMUTABLE);
      return;

    case TRACE_VAL_UNKNOWN:
      trace_unknown(c, ctx, dst_value, PONY_TRACE_IMMUTABLE);
      return;

    case TRACE_MUT_KNOWN:
      trace_known(c, ctx, dst_value, src_type, PONY_TRACE_MUTABLE);
      return;

    case TRACE_MUT_UNKNOWN:
      trace_unknown(c, ctx, dst_value, PONY_TRACE_MUTABLE);
      return;

    case TRACE_TAG_KNOWN:
      trace_known(c, ctx, dst_value, src_type, PONY_TRACE_OPAQUE);
      return;

    case TRACE_TAG_UNKNOWN:
      trace_unknown(c, ctx, dst_value, PONY_TRACE_OPAQUE);
      return;

    case TRACE_STATIC:
      trace_static(c, ctx, dst_value, src_type, dst_type);
      return;

    case TRACE_DYNAMIC:
    {
      LLVMBasicBlockRef next_block = codegen_block(c, "");
      trace_dynamic(c, ctx, dst_value, src_type, dst_type, NULL, next_block);
      LLVMBuildBr(c->builder, next_block);
      LLVMPositionBuilderAtEnd(c->builder, next_block);
      return;
    }

    case TRACE_TUPLE:
      trace_tuple(c, ctx, src_value, dst_value, src_type, dst_type);
      return;
  }
}