#pragma once
#include "Code/Var.h"
#include "Code/Operand.h"
#include "Value.h"

namespace storm {
	STORM_PKG(core.lang);

	/**
	 * Interface for replacing active functions.
	 */

	class ReplaceContext;
	class ReplaceTasks;
	class Function;

	// Attempt to replace the code in the function 'code' (assumed to point to a code segment
	// managed by Storm) with the new function 'Function'. Generates thunks as necessary. Returns
	// true on success and false otherwise. May also throw exceptions in case the new function does
	// not compile properly.
	// This function is expected to be called *after* types etc. have been update globally. As such,
	// it does not accound for the type equivalence that was previously computed in a ReplaceContext
	// when doing comparisons (it is not possible to do this, since we compile arbitrary code).
	Bool replaceActiveFunction(const void *oldFn, Function *newFn, ReplaceTasks *tasks);


	/**
	 * Data structure to keep track of which data to move.
	 */
	class DataMove {
		STORM_VALUE;
	public:
		// Variable to copy *from*. Expected to have the right size.
		code::Var source;

		// Target offset in the stack frame. Might not be of the right size.
		code::Operand target;

		// Type to be copied. Used to determine if constructors need to be called.
		Value type;

		// Create.
		STORM_CTOR DataMove(code::Var source, code::Operand target, Value type)
			: source(source), target(target), type(type) {}
	};

}
