/* Call module for 'compile' command.

   Copyright (C) 2014-2022 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "compile-object-run.h"
#include "value.h"
#include "infcall.h"
#include "objfiles.h"
#include "compile-internal.h"
#include "dummy-frame.h"
#include "block.h"
#include "valprint.h"
#include "compile.h"

/* Helper for do_module_cleanup.  */

struct do_module_cleanup
{
  do_module_cleanup (int *ptr, compile_module_up &&mod)
    : executedp (ptr),
      module (std::move (mod))
  {
  }

  DISABLE_COPY_AND_ASSIGN (do_module_cleanup);

  /* Boolean to set true upon a call of do_module_cleanup.
     The pointer may be NULL.  */
  int *executedp;

  /* The compile module.  */
  compile_module_up module;
};

/* Cleanup everything after the inferior function dummy frame gets
   discarded.  */

static dummy_frame_dtor_ftype do_module_cleanup;
static void
do_module_cleanup (void *arg, int registers_valid)
{
  struct do_module_cleanup *data = (struct do_module_cleanup *) arg;

  if (data->executedp != NULL)
    {
      *data->executedp = 1;

      /* This code cannot be in compile_object_run as OUT_VALUE_TYPE
	 no longer exists there.  */
      if (data->module->scope == COMPILE_I_PRINT_ADDRESS_SCOPE
	  || data->module->scope == COMPILE_I_PRINT_VALUE_SCOPE)
	{
	  struct value *addr_value;
	  struct type *ptr_type
	    = lookup_pointer_type (data->module->out_value_type);

	  addr_value = value_from_pointer (ptr_type,
					   data->module->out_value_addr);

	  /* SCOPE_DATA would be stale unless EXECUTEDP != NULL.  */
	  compile_print_value (value_ind (addr_value),
			       data->module->scope_data);
	}
    }

  /* We have to make a copy of the name so that we can unlink the
     underlying file -- removing the objfile will cause the name to be
     freed, so we can't simply keep a reference to it.  */
  std::string objfile_name_s = objfile_name (data->module->objfile);
  for (objfile *objfile : current_program_space->objfiles ())
    if ((objfile->flags & OBJF_USERLOADED) == 0
	&& objfile_name_s == objfile_name (objfile))
      {
	objfile->unlink ();

	/* It may be a bit too pervasive in this dummy_frame dtor callback.  */
	clear_symtab_users (0);

	break;
      }

  /* Delete the .c file.  */
  unlink (data->module->source_file.c_str ());

  /* Delete the .o file.  */
  unlink (objfile_name_s.c_str ());

  delete data;
}

/* Create a copy of FUNC_TYPE that is independent of OBJFILE.  */

static type *
create_copied_type_recursive (objfile *objfile, type *func_type)
{
  htab_up copied_types = create_copied_types_hash (objfile);
  func_type = copy_type_recursive (objfile, func_type, copied_types.get ());
  return func_type;
}

/* Perform inferior call of MODULE.  This function may throw an error.
   This function may leave files referenced by MODULE on disk until
   the inferior call dummy frame is discarded.  This function may throw errors.
   Thrown errors and left MODULE files are unrelated events.  Caller must no
   longer touch MODULE's memory after this function has been called.  */

void
compile_object_run (compile_module_up &&module)
{
  struct value *func_val;
  struct do_module_cleanup *data;
  int dtor_found, executed = 0;
  struct symbol *func_sym = module->func_sym;
  CORE_ADDR regs_addr = module->regs_addr;
  struct objfile *objfile = module->objfile;

  data = new struct do_module_cleanup (&executed, std::move (module));

  try
    {
      struct type *func_type = func_sym->type ();
      int current_arg = 0;
      struct value **vargs;

      /* OBJFILE may disappear while FUNC_TYPE is still in use as a
	 result of the call to DO_MODULE_CLEANUP below, so we need a copy
	 that does not depend on the objfile in anyway.  */
      func_type = create_copied_type_recursive (objfile, func_type);

      gdb_assert (func_type->code () == TYPE_CODE_FUNC);
      func_val = value_from_pointer (lookup_pointer_type (func_type),
				   BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (func_sym)));

      vargs = XALLOCAVEC (struct value *, func_type->num_fields ());
      if (func_type->num_fields () >= 1)
	{
	  gdb_assert (regs_addr != 0);
	  vargs[current_arg] = value_from_pointer
			  (func_type->field (current_arg).type (), regs_addr);
	  ++current_arg;
	}
      if (func_type->num_fields () >= 2)
	{
	  gdb_assert (data->module->out_value_addr != 0);
	  vargs[current_arg] = value_from_pointer
	       (func_type->field (current_arg).type (),
		data->module->out_value_addr);
	  ++current_arg;
	}
      gdb_assert (current_arg == func_type->num_fields ());
      auto args = gdb::make_array_view (vargs, func_type->num_fields ());
      call_function_by_hand_dummy (func_val, NULL, args,
				   do_module_cleanup, data);
    }
  catch (const gdb_exception_error &ex)
    {
      /* In the case of DTOR_FOUND or in the case of EXECUTED nothing
	 needs to be done.  */
      dtor_found = find_dummy_frame_dtor (do_module_cleanup, data);
      if (!executed)
	data->executedp = NULL;
      gdb_assert (!(dtor_found && executed));
      if (!dtor_found && !executed)
	do_module_cleanup (data, 0);
      throw;
    }

  dtor_found = find_dummy_frame_dtor (do_module_cleanup, data);
  gdb_assert (!dtor_found && executed);
}
