//===--- EvalEmitter.cpp - Instruction emitter for the VM -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "EvalEmitter.h"
#include "Context.h"
#include "IntegralAP.h"
#include "Interp.h"
#include "clang/AST/DeclCXX.h"

using namespace clang;
using namespace clang::interp;

EvalEmitter::EvalEmitter(Context &Ctx, Program &P, State &Parent,
                         InterpStack &Stk)
    : Ctx(Ctx), P(P), S(Parent, P, Stk, Ctx, this), EvalResult(&Ctx) {}

EvalEmitter::~EvalEmitter() {
  for (auto &V : Locals) {
    Block *B = reinterpret_cast<Block *>(V.get());
    if (B->isInitialized())
      B->invokeDtor();
  }
}

/// Clean up all our resources. This needs to done in failed evaluations before
/// we call InterpStack::clear(), because there might be a Pointer on the stack
/// pointing into a Block in the EvalEmitter.
void EvalEmitter::cleanup() { S.cleanup(); }

EvaluationResult EvalEmitter::interpretExpr(const Expr *E,
                                            bool ConvertResultToRValue,
                                            bool DestroyToplevelScope) {
  S.setEvalLocation(E->getExprLoc());
  this->ConvertResultToRValue = ConvertResultToRValue && !isa<ConstantExpr>(E);
  this->CheckFullyInitialized = isa<ConstantExpr>(E);
  EvalResult.setSource(E);

  if (!this->visitExpr(E, DestroyToplevelScope)) {
    // EvalResult may already have a result set, but something failed
    // after that (e.g. evaluating destructors).
    EvalResult.setInvalid();
  }

  return std::move(this->EvalResult);
}

EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD, const Expr *Init,
                                            bool CheckFullyInitialized) {
  assert(VD);
  assert(Init);
  this->CheckFullyInitialized = CheckFullyInitialized;
  S.EvaluatingDecl = VD;
  S.setEvalLocation(VD->getLocation());
  EvalResult.setSource(VD);

  QualType T = VD->getType();
  this->ConvertResultToRValue = !Init->isGLValue() && !T->isPointerType() &&
                                !T->isObjCObjectPointerType();
  EvalResult.setSource(VD);

  if (!this->visitDeclAndReturn(VD, Init, S.inConstantContext()))
    EvalResult.setInvalid();

  S.EvaluatingDecl = nullptr;
  updateGlobalTemporaries();
  return std::move(this->EvalResult);
}

EvaluationResult EvalEmitter::interpretAsPointer(const Expr *E,
                                                 PtrCallback PtrCB) {

  S.setEvalLocation(E->getExprLoc());
  this->ConvertResultToRValue = false;
  this->CheckFullyInitialized = false;
  this->PtrCB = PtrCB;
  EvalResult.setSource(E);

  if (!this->visitExpr(E, /*DestroyToplevelScope=*/true)) {
    // EvalResult may already have a result set, but something failed
    // after that (e.g. evaluating destructors).
    EvalResult.setInvalid();
  }

  return std::move(this->EvalResult);
}

bool EvalEmitter::interpretCall(const FunctionDecl *FD, const Expr *E) {
  // Add parameters to the parameter map. The values in the ParamOffset don't
  // matter in this case as reading from them can't ever work.
  for (const ParmVarDecl *PD : FD->parameters()) {
    this->Params.insert({PD, {0, false}});
  }

  return this->visitExpr(E, /*DestroyToplevelScope=*/false);
}

void EvalEmitter::emitLabel(LabelTy Label) { CurrentLabel = Label; }

EvalEmitter::LabelTy EvalEmitter::getLabel() { return NextLabel++; }

Scope::Local EvalEmitter::createLocal(Descriptor *D) {
  // Allocate memory for a local.
  auto Memory = std::make_unique<char[]>(sizeof(Block) + D->getAllocSize());
  auto *B = new (Memory.get()) Block(Ctx.getEvalID(), D, /*isStatic=*/false);
  B->invokeCtor();

  // Initialize local variable inline descriptor.
  InlineDescriptor &Desc = *reinterpret_cast<InlineDescriptor *>(B->rawData());
  Desc.Desc = D;
  Desc.Offset = sizeof(InlineDescriptor);
  Desc.IsActive = false;
  Desc.IsBase = false;
  Desc.IsFieldMutable = false;
  Desc.IsConst = false;
  Desc.IsInitialized = false;

  // Register the local.
  unsigned Off = Locals.size();
  Locals.push_back(std::move(Memory));
  return {Off, D};
}

bool EvalEmitter::jumpTrue(const LabelTy &Label) {
  if (isActive()) {
    if (S.Stk.pop<bool>())
      ActiveLabel = Label;
  }
  return true;
}

bool EvalEmitter::jumpFalse(const LabelTy &Label) {
  if (isActive()) {
    if (!S.Stk.pop<bool>())
      ActiveLabel = Label;
  }
  return true;
}

bool EvalEmitter::jump(const LabelTy &Label) {
  if (isActive())
    CurrentLabel = ActiveLabel = Label;
  return true;
}

bool EvalEmitter::fallthrough(const LabelTy &Label) {
  if (isActive())
    ActiveLabel = Label;
  CurrentLabel = Label;
  return true;
}

bool EvalEmitter::speculate(const CallExpr *E, const LabelTy &EndLabel) {
  size_t StackSizeBefore = S.Stk.size();
  const Expr *Arg = E->getArg(0);
  if (!this->visit(Arg)) {
    S.Stk.clearTo(StackSizeBefore);

    if (S.inConstantContext() || Arg->HasSideEffects(S.getASTContext()))
      return this->emitBool(false, E);
    return Invalid(S, OpPC);
  }

  PrimType T = Ctx.classify(Arg->getType()).value_or(PT_Ptr);
  if (T == PT_Ptr) {
    const auto &Ptr = S.Stk.pop<Pointer>();
    return this->emitBool(CheckBCPResult(S, Ptr), E);
  }

  // Otherwise, this is fine!
  if (!this->emitPop(T, E))
    return false;
  return this->emitBool(true, E);
}

template <PrimType OpType> bool EvalEmitter::emitRet(SourceInfo Info) {
  if (!isActive())
    return true;

  using T = typename PrimConv<OpType>::T;
  EvalResult.takeValue(S.Stk.pop<T>().toAPValue(Ctx.getASTContext()));
  return true;
}

template <> bool EvalEmitter::emitRet<PT_Ptr>(SourceInfo Info) {
  if (!isActive())
    return true;

  const Pointer &Ptr = S.Stk.pop<Pointer>();

  if (Ptr.isFunctionPointer()) {
    EvalResult.takeValue(Ptr.toAPValue(Ctx.getASTContext()));
    return true;
  }

  // If we're returning a raw pointer, call our callback.
  if (this->PtrCB)
    return (*this->PtrCB)(Ptr);

  if (!EvalResult.checkReturnValue(S, Ctx, Ptr, Info))
    return false;
  if (CheckFullyInitialized && !EvalResult.checkFullyInitialized(S, Ptr))
    return false;

  // Implicitly convert lvalue to rvalue, if requested.
  if (ConvertResultToRValue) {
    if (!Ptr.isZero() && !Ptr.isDereferencable())
      return false;

    if (Ptr.pointsToStringLiteral() && Ptr.isArrayRoot())
      return false;

    if (!Ptr.isZero() && !CheckFinalLoad(S, OpPC, Ptr))
      return false;

    // Never allow reading from a non-const pointer, unless the memory
    // has been created in this evaluation.
    if (!Ptr.isZero() && !Ptr.isConst() && Ptr.isBlockPointer() &&
        Ptr.block()->getEvalID() != Ctx.getEvalID())
      return false;

    if (std::optional<APValue> V =
            Ptr.toRValue(Ctx, EvalResult.getSourceType())) {
      EvalResult.takeValue(std::move(*V));
    } else {
      return false;
    }
  } else {
    // If this is pointing to a local variable, just return
    // the result, even if the pointer is dead.
    // This will later be diagnosed by CheckLValueConstantExpression.
    if (Ptr.isBlockPointer() && !Ptr.block()->isStatic()) {
      EvalResult.takeValue(Ptr.toAPValue(Ctx.getASTContext()));
      return true;
    }

    if (!Ptr.isLive() && !Ptr.isTemporary())
      return false;

    EvalResult.takeValue(Ptr.toAPValue(Ctx.getASTContext()));
  }

  return true;
}

bool EvalEmitter::emitRetVoid(SourceInfo Info) {
  EvalResult.setValid();
  return true;
}

bool EvalEmitter::emitRetValue(SourceInfo Info) {
  const auto &Ptr = S.Stk.pop<Pointer>();

  if (!EvalResult.checkReturnValue(S, Ctx, Ptr, Info))
    return false;
  if (CheckFullyInitialized && !EvalResult.checkFullyInitialized(S, Ptr))
    return false;

  if (std::optional<APValue> APV =
          Ptr.toRValue(S.getASTContext(), EvalResult.getSourceType())) {
    EvalResult.takeValue(std::move(*APV));
    return true;
  }

  EvalResult.setInvalid();
  return false;
}

bool EvalEmitter::emitGetPtrLocal(uint32_t I, SourceInfo Info) {
  if (!isActive())
    return true;

  Block *B = getLocal(I);
  S.Stk.push<Pointer>(B, sizeof(InlineDescriptor));
  return true;
}

template <PrimType OpType>
bool EvalEmitter::emitGetLocal(uint32_t I, SourceInfo Info) {
  if (!isActive())
    return true;

  using T = typename PrimConv<OpType>::T;

  Block *B = getLocal(I);

  if (!CheckLocalLoad(S, OpPC, B))
    return false;

  S.Stk.push<T>(*reinterpret_cast<T *>(B->data()));
  return true;
}

template <PrimType OpType>
bool EvalEmitter::emitSetLocal(uint32_t I, SourceInfo Info) {
  if (!isActive())
    return true;

  using T = typename PrimConv<OpType>::T;

  Block *B = getLocal(I);
  *reinterpret_cast<T *>(B->data()) = S.Stk.pop<T>();
  InlineDescriptor &Desc = *reinterpret_cast<InlineDescriptor *>(B->rawData());
  Desc.IsInitialized = true;

  return true;
}

bool EvalEmitter::emitDestroy(uint32_t I, SourceInfo Info) {
  if (!isActive())
    return true;

  for (auto &Local : Descriptors[I]) {
    Block *B = getLocal(Local.Offset);
    S.deallocate(B);
  }

  return true;
}

bool EvalEmitter::emitGetLocalEnabled(uint32_t I, SourceInfo Info) {
  if (!isActive())
    return true;

  Block *B = getLocal(I);
  const InlineDescriptor &Desc =
      *reinterpret_cast<InlineDescriptor *>(B->rawData());

  S.Stk.push<bool>(Desc.IsActive);
  return true;
}

bool EvalEmitter::emitEnableLocal(uint32_t I, SourceInfo Info) {
  if (!isActive())
    return true;

  // FIXME: This is a little dirty, but to avoid adding a flag to
  // InlineDescriptor that's only ever useful on the toplevel of local
  // variables, we reuse the IsActive flag for the enabled state. We should
  // probably use a different struct than InlineDescriptor for the block-level
  // inline descriptor of local varaibles.
  Block *B = getLocal(I);
  InlineDescriptor &Desc = *reinterpret_cast<InlineDescriptor *>(B->rawData());
  Desc.IsActive = true;
  return true;
}

/// Global temporaries (LifetimeExtendedTemporary) carry their value
/// around as an APValue, which codegen accesses.
/// We set their value once when creating them, but we don't update it
/// afterwards when code changes it later.
/// This is what we do here.
void EvalEmitter::updateGlobalTemporaries() {
  for (const auto &[E, Temp] : S.SeenGlobalTemporaries) {
    UnsignedOrNone GlobalIndex = P.getGlobal(E);
    assert(GlobalIndex);
    const Pointer &Ptr = P.getPtrGlobal(*GlobalIndex);
    APValue *Cached = Temp->getOrCreateValue(true);
    if (OptPrimType T = Ctx.classify(E->getType())) {
      TYPE_SWITCH(*T,
                  { *Cached = Ptr.deref<T>().toAPValue(Ctx.getASTContext()); });
    } else {
      if (std::optional<APValue> APV =
              Ptr.toRValue(Ctx, Temp->getTemporaryExpr()->getType()))
        *Cached = *APV;
    }
  }
  S.SeenGlobalTemporaries.clear();
}

//===----------------------------------------------------------------------===//
// Opcode evaluators
//===----------------------------------------------------------------------===//

#define GET_EVAL_IMPL
#include "Opcodes.inc"
#undef GET_EVAL_IMPL
