// 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 uint, C type uintgo.
  RFT_UINT,
  // Go type uint8, C type uint8_t.
  RFT_UINT8,
  // Go type uint16, C type uint16_t.
  RFT_UINT16,
  // 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_UINT:
	  t = Type::lookup_integer_type("uint");
	  break;

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

	case RFT_UINT16:
	  t = Type::lookup_integer_type("uint16");
	  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(Gogo* gogo, 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_UINT:
    case RFT_UINT8:
    case RFT_UINT16:
    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);
	Type_context context(t, false);
	e->determine_type(gogo, &context);
	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(gogo);
	  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(Gogo* gogo, 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(gogo, 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;
}
