// runtime.cc -- runtime functions called by generated code

// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "go-system.h"

#include "gogo.h"
#include "types.h"
#include "expressions.h"
#include "runtime.h"

// The frontend generates calls to various runtime functions.  They
// are implemented in libgo/runtime.  This is how the runtime
// functions are represented in the frontend.  Note that there is
// currently nothing which ensures that the compiler's understanding
// of the runtime function matches the actual implementation in
// libgo/runtime.

// Parameter and result types used by runtime functions.

enum Runtime_function_type
{
  // General indicator that value is not used.
  RFT_VOID,
  // Go untyped bool, C type _Bool.
  RFT_BOOL,
  // Go type *bool, C type _Bool*.
  RFT_BOOLPTR,
  // Go type int, C type intgo.
  RFT_INT,
  // Go type uint8, C type uint8_t.
  RFT_UINT8,
  // Go type int32, C type int32_t.
  RFT_INT32,
  // Go type uint32, C type uint32_t.
  RFT_UINT32,
  // Go type int64, C type int64_t.
  RFT_INT64,
  // Go type uint64, C type uint64_t.
  RFT_UINT64,
  // Go type uintptr, C type uintptr_t.
  RFT_UINTPTR,
  // Go type rune, C type int32_t.
  RFT_RUNE,
  // Go type float64, C type double.
  RFT_FLOAT64,
  // Go type complex64, C type __complex float.
  RFT_COMPLEX64,
  // Go type complex128, C type __complex double.
  RFT_COMPLEX128,
  // Go type string, C type struct __go_string.
  RFT_STRING,
  // Go type unsafe.Pointer, C type "void *".
  RFT_POINTER,
  // Go type []any, C type struct __go_open_array.
  RFT_SLICE,
  // Go type map[any]any, C type struct __go_map *.
  RFT_MAP,
  // Go type chan any, C type struct __go_channel *.
  RFT_CHAN,
  // Go type non-empty interface, C type struct __go_interface.
  RFT_IFACE,
  // Go type interface{}, C type struct __go_empty_interface.
  RFT_EFACE,
  // Pointer to Go type descriptor.
  RFT_TYPE,
  // [2]string.
  RFT_ARRAY2STRING,
  // [3]string.
  RFT_ARRAY3STRING,
  // [4]string.
  RFT_ARRAY4STRING,
  // [5]string.
  RFT_ARRAY5STRING,

  NUMBER_OF_RUNTIME_FUNCTION_TYPES
};

// The Type structures for the runtime function types.

static Type* runtime_function_types[NUMBER_OF_RUNTIME_FUNCTION_TYPES];

// Get the Type for a Runtime_function_type code.

static Type*
runtime_function_type(Runtime_function_type bft)
{
  go_assert(bft < NUMBER_OF_RUNTIME_FUNCTION_TYPES);
  Type* any = Type::make_pointer_type(Type::make_void_type());
  if (runtime_function_types[bft] == NULL)
    {
      const Location bloc = Linemap::predeclared_location();
      Type* t;
      switch (bft)
	{
	default:
	case RFT_VOID:
	  go_unreachable();

	case RFT_BOOL:
	  t = Type::make_boolean_type();
	  break;

	case RFT_BOOLPTR:
	  t = Type::make_pointer_type(Type::lookup_bool_type());
	  break;

	case RFT_INT:
	  t = Type::lookup_integer_type("int");
	  break;

	case RFT_UINT8:
	  t = Type::lookup_integer_type("uint8");
	  break;

	case RFT_INT32:
	  t = Type::lookup_integer_type("int32");
	  break;

	case RFT_UINT32:
	  t = Type::lookup_integer_type("uint32");
	  break;

	case RFT_INT64:
	  t = Type::lookup_integer_type("int64");
	  break;

	case RFT_UINT64:
	  t = Type::lookup_integer_type("uint64");
	  break;

	case RFT_RUNE:
	  t = Type::lookup_integer_type("int32");
	  break;

	case RFT_UINTPTR:
	  t = Type::lookup_integer_type("uintptr");
	  break;

	case RFT_FLOAT64:
	  t = Type::lookup_float_type("float64");
	  break;

	case RFT_COMPLEX64:
	  t = Type::lookup_complex_type("complex64");
	  break;

	case RFT_COMPLEX128:
	  t = Type::lookup_complex_type("complex128");
	  break;

	case RFT_STRING:
	  t = Type::lookup_string_type();
	  break;

	case RFT_POINTER:
	  t = Type::make_pointer_type(Type::make_void_type());
	  break;

	case RFT_SLICE:
	  t = Type::make_array_type(any, NULL);
	  break;

	case RFT_MAP:
	  t = Type::make_map_type(any, any, bloc);
	  break;

	case RFT_CHAN:
	  t = Type::make_channel_type(true, true, any);
	  break;

	case RFT_IFACE:
	  {
	    Typed_identifier_list* methods = new Typed_identifier_list();
	    Type* mtype = Type::make_function_type(NULL, NULL, NULL, bloc);
	    methods->push_back(Typed_identifier("x", mtype, bloc));
	    Interface_type* it = Type::make_interface_type(methods, bloc);
	    it->finalize_methods();
	    t = it;
	  }
	  break;

	case RFT_EFACE:
	  t = Type::make_empty_interface_type(bloc);
	  break;

	case RFT_TYPE:
	  t = Type::make_type_descriptor_ptr_type();
	  break;

	case RFT_ARRAY2STRING:
	  {
	    Array_type* at =
	      Type::make_array_type(Type::make_string_type(),
				    Expression::make_integer_ul(2, NULL,
								bloc));
	    at->set_is_array_incomparable();
	    t = at;
	  }
	  break;

	case RFT_ARRAY3STRING:
	  {
	    Array_type* at =
	      Type::make_array_type(Type::make_string_type(),
				    Expression::make_integer_ul(3, NULL,
								bloc));
	    at->set_is_array_incomparable();
	    t = at;
	  }
	  break;

	case RFT_ARRAY4STRING:
	  {
	    Array_type* at =
	      Type::make_array_type(Type::make_string_type(),
				    Expression::make_integer_ul(4, NULL,
								bloc));
	    at->set_is_array_incomparable();
	    t = at;
	  }
	  break;

	case RFT_ARRAY5STRING:
	  {
	    Array_type* at =
	      Type::make_array_type(Type::make_string_type(),
				    Expression::make_integer_ul(5, NULL,
								bloc));
	    at->set_is_array_incomparable();
	    t = at;
	  }
	  break;
	}

      runtime_function_types[bft] = t;
    }

  return runtime_function_types[bft];
}

// Convert an expression to the type to pass to a runtime function.

static Expression*
convert_to_runtime_function_type(Runtime_function_type bft, Expression* e,
				 Location loc)
{
  switch (bft)
    {
    default:
    case RFT_VOID:
      go_unreachable();

    case RFT_BOOL:
    case RFT_BOOLPTR:
    case RFT_INT:
    case RFT_UINT8:
    case RFT_INT32:
    case RFT_UINT32:
    case RFT_INT64:
    case RFT_UINT64:
    case RFT_UINTPTR:
    case RFT_RUNE:
    case RFT_FLOAT64:
    case RFT_COMPLEX64:
    case RFT_COMPLEX128:
    case RFT_STRING:
    case RFT_POINTER:
      {
	Type* t = runtime_function_type(bft);
	if (!Type::are_identical(t, e->type(), true, NULL))
	  e = Expression::make_cast(t, e, loc);
	return e;
      }

    case RFT_SLICE:
    case RFT_MAP:
    case RFT_CHAN:
    case RFT_IFACE:
    case RFT_EFACE:
    case RFT_ARRAY2STRING:
    case RFT_ARRAY3STRING:
    case RFT_ARRAY4STRING:
    case RFT_ARRAY5STRING:
      return Expression::make_unsafe_cast(runtime_function_type(bft), e, loc);

    case RFT_TYPE:
      go_assert(e->type() == Type::make_type_descriptor_ptr_type());
      return e;
    }
}

// Convert all the types used for runtime functions to the backend
// representation.

void
Runtime::convert_types(Gogo* gogo)
{
  for (int i = 0; i < static_cast<int>(NUMBER_OF_RUNTIME_FUNCTION_TYPES); ++i)
    {
      Type* t = runtime_function_types[i];
      if (t != NULL && t->named_type() != NULL)
	{
	  bool r = t->verify();
	  go_assert(r);
	  t->named_type()->convert(gogo);
	}
    }
}

// The type used to define a runtime function.

struct Runtime_function
{
  // Function name.
  const char* name;
  // Parameter types.  Never more than 6, as it happens.  RFT_VOID if
  // not used.
  Runtime_function_type parameter_types[6];
  // Result types.  Never more than 2, as it happens.  RFT_VOID if not
  // used.
  Runtime_function_type result_types[2];
};

static const Runtime_function runtime_functions[] =
{

#define DEF_GO_RUNTIME(CODE, NAME, PARAMS, RESULTS) { NAME, PARAMS, RESULTS } ,

#include "runtime.def"

#undef DEF_GO_RUNTIME

};

static Named_object*
runtime_function_declarations[Runtime::NUMBER_OF_FUNCTIONS];

// Get the declaration of a runtime function.

Named_object*
Runtime::runtime_declaration(Function code)
{
  go_assert(code < Runtime::NUMBER_OF_FUNCTIONS);
  if (runtime_function_declarations[code] == NULL)
    {
      const Runtime_function* pb = &runtime_functions[code];

      Location bloc = Linemap::predeclared_location();

      Typed_identifier_list* param_types = NULL;
      if (pb->parameter_types[0] != RFT_VOID)
	{
	  param_types = new Typed_identifier_list();
	  for (unsigned int i = 0;
	       i < (sizeof(pb->parameter_types)
		    / sizeof (pb->parameter_types[0]));
	       i++)
	    {
	      if (pb->parameter_types[i] == RFT_VOID)
		break;
	      Type* t = runtime_function_type(pb->parameter_types[i]);
	      param_types->push_back(Typed_identifier("", t, bloc));
	    }
	}

      Typed_identifier_list* result_types = NULL;
      if (pb->result_types[0] != RFT_VOID)
	{
	  result_types = new Typed_identifier_list();
	  for (unsigned int i = 0;
	       i < sizeof(pb->result_types) / sizeof(pb->result_types[0]);
	       i++)
	    {
	      if (pb->result_types[i] == RFT_VOID)
		break;
	      Type* t = runtime_function_type(pb->result_types[i]);
	      result_types->push_back(Typed_identifier("", t, bloc));
	    }
	}

      Function_type* fntype = Type::make_function_type(NULL, param_types,
						       result_types, bloc);
      const char* n = pb->name;
      const char* n1 = strchr(n, '.');
      if (n1 != NULL)
	n = n1 + 1;
      Named_object* no = Named_object::make_function_declaration(n, NULL,
								 fntype, bloc);
      no->func_declaration_value()->set_asm_name(pb->name);

      runtime_function_declarations[code] = no;
    }

  return runtime_function_declarations[code];
}

// Make a call to a runtime function.

Call_expression*
Runtime::make_call(Runtime::Function code, Location loc,
		   int param_count, ...)
{
  go_assert(code < Runtime::NUMBER_OF_FUNCTIONS);

  const Runtime_function* pb = &runtime_functions[code];

  go_assert(static_cast<size_t>(param_count)
	     <= sizeof(pb->parameter_types) / sizeof(pb->parameter_types[0]));

  Named_object* no = runtime_declaration(code);
  Expression* func = Expression::make_func_reference(no, NULL, loc);

  Expression_list* args = new Expression_list();
  args->reserve(param_count);

  va_list ap;
  va_start(ap, param_count);
  for (int i = 0; i < param_count; ++i)
    {
      Expression* e = va_arg(ap, Expression*);
      Runtime_function_type rft = pb->parameter_types[i];
      args->push_back(convert_to_runtime_function_type(rft, e, loc));
    }
  va_end(ap);

  return Expression::make_call(func, args, false, loc);
}

// Get the runtime code for a named builtin function.  This is used as a helper
// when creating function references for call expressions.  Every reference to
// a builtin runtime function should have the associated runtime code.  If the
// name is ambiguous and can refer to many runtime codes, return
// NUMBER_OF_FUNCTIONS.

Runtime::Function
Runtime::name_to_code(const std::string& name)
{
  Function code = Runtime::NUMBER_OF_FUNCTIONS;

  // Look through the known names for a match.
  for (size_t i = 0; i < Runtime::NUMBER_OF_FUNCTIONS; i++)
    {
      const char* runtime_function_name = runtime_functions[i].name;
      if (strcmp(runtime_function_name, name.c_str()) == 0)
        code = static_cast<Runtime::Function>(i);
      // The names in the table have "runtime." prefix. We may be
      // called with a name without the prefix. Try matching
      // without the prefix as well.
      if (strncmp(runtime_function_name, "runtime.", 8) == 0
          && strcmp(runtime_function_name + 8, name.c_str()) == 0)
        code = static_cast<Runtime::Function>(i);
    }
  return code;
}
