// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_VM_INTERPRETER_H_
#define RUNTIME_VM_INTERPRETER_H_

#include "vm/globals.h"
#if !defined(DART_PRECOMPILED_RUNTIME)

#include "vm/compiler/method_recognizer.h"
#include "vm/constants_kbc.h"

namespace dart {

class Isolate;
class RawObject;
class InterpreterSetjmpBuffer;
class Thread;
class Code;
class Array;
class RawICData;
class RawImmutableArray;
class RawArray;
class RawObjectPool;
class RawFunction;
class RawSubtypeTestCache;
class ObjectPointerVisitor;

// Interpreter intrinsic handler. It is invoked on entry to the intrinsified
// function via Intrinsic bytecode before the frame is setup.
// If the handler returns true then Intrinsic bytecode works as a return
// instruction returning the value in result. Otherwise interpreter proceeds to
// execute the body of the function.
typedef bool (*IntrinsicHandler)(Thread* thread,
                                 RawObject** FP,
                                 RawObject** result);

class Interpreter {
 public:
  static const uword kInterpreterStackUnderflowSize = 0x80;

  Interpreter();
  ~Interpreter();

  // The currently executing Interpreter instance, which is associated to the
  // current isolate
  static Interpreter* Current();

  // Low address (KBC stack grows up).
  uword stack_base() const { return stack_base_; }
  // High address (KBC stack grows up).
  uword stack_limit() const { return stack_limit_; }

  // Returns true if the interpreter's stack contains the given frame.
  // TODO(regis): We should rely on a new thread vm_tag to identify an
  // interpreter frame and not need this HasFrame() method.
  bool HasFrame(uword frame) const {
    return frame >= stack_base() && frame <= get_fp();
  }

  // Identify an entry frame by looking at its pc marker value.
  static bool IsEntryFrameMarker(uword pc) { return (pc & 2) != 0; }

  // Call on program start.
  static void InitOnce();

  RawObject* Call(const Function& function,
                  const Array& arguments_descriptor,
                  const Array& arguments,
                  Thread* thread);

  RawObject* Call(RawFunction* function,
                  RawArray* argdesc,
                  intptr_t argc,
                  RawObject* const* argv,
                  Thread* thread);

  void JumpToFrame(uword pc, uword sp, uword fp, Thread* thread);

  uword get_sp() const { return reinterpret_cast<uword>(fp_); }  // Yes, fp_.
  uword get_fp() const { return reinterpret_cast<uword>(fp_); }
  uword get_pc() const { return pc_; }

  enum IntrinsicId {
#define V(test_class_name, test_function_name, enum_name, type, fp)            \
  k##enum_name##Intrinsic,
    ALL_INTRINSICS_LIST(V) GRAPH_INTRINSICS_LIST(V)
#undef V
        kIntrinsicCount,
  };

  static bool IsSupportedIntrinsic(IntrinsicId id) {
    return intrinsics_[id] != NULL;
  }

  void VisitObjectPointers(ObjectPointerVisitor* visitor);

 private:
  uintptr_t* stack_;
  uword stack_base_;
  uword stack_limit_;

  RawObject** fp_;
  uword pc_;
  DEBUG_ONLY(uint64_t icount_;)

  InterpreterSetjmpBuffer* last_setjmp_buffer_;

  RawObjectPool* pp_;  // Pool Pointer.
  RawArray* argdesc_;  // Arguments Descriptor: used to pass information between
                       // call instruction and the function entry.
  RawObject* special_[KernelBytecode::kSpecialIndexCount];

  static IntrinsicHandler intrinsics_[kIntrinsicCount];

  void Exit(Thread* thread,
            RawObject** base,
            RawObject** exit_frame,
            uint32_t* pc);

  void CallRuntime(Thread* thread,
                   RawObject** base,
                   RawObject** exit_frame,
                   uint32_t* pc,
                   intptr_t argc_tag,
                   RawObject** args,
                   RawObject** result,
                   uword target);

  bool Invoke(Thread* thread,
              RawObject** call_base,
              RawObject** call_top,
              uint32_t** pc,
              RawObject*** FP,
              RawObject*** SP);

  bool ProcessInvocation(bool* invoked,
                         Thread* thread,
                         RawFunction* function,
                         RawObject** call_base,
                         RawObject** call_top,
                         uint32_t** pc,
                         RawObject*** FP,
                         RawObject*** SP);

  bool InvokeCompiled(Thread* thread,
                      RawFunction* function,
                      RawObject** call_base,
                      RawObject** call_top,
                      uint32_t** pc,
                      RawObject*** FP,
                      RawObject*** SP);

  bool Deoptimize(Thread* thread,
                  uint32_t** pc,
                  RawObject*** FP,
                  RawObject*** SP,
                  bool is_lazy);

  void InlineCacheMiss(int checked_args,
                       Thread* thread,
                       RawICData* icdata,
                       RawObject** call_base,
                       RawObject** top,
                       uint32_t* pc,
                       RawObject** FP,
                       RawObject** SP);

  bool InstanceCall1(Thread* thread,
                     RawICData* icdata,
                     RawObject** call_base,
                     RawObject** call_top,
                     uint32_t** pc,
                     RawObject*** FP,
                     RawObject*** SP,
                     bool optimized);

  bool InstanceCall2(Thread* thread,
                     RawICData* icdata,
                     RawObject** call_base,
                     RawObject** call_top,
                     uint32_t** pc,
                     RawObject*** FP,
                     RawObject*** SP,
                     bool optimized);

  void PrepareForTailCall(RawCode* code,
                          RawImmutableArray* args_desc,
                          RawObject** FP,
                          RawObject*** SP,
                          uint32_t** pc);

  bool AssertAssignable(Thread* thread,
                        uint32_t* pc,
                        RawObject** FP,
                        RawObject** call_top,
                        RawObject** args,
                        RawSubtypeTestCache* cache);

  bool AllocateInt64Box(Thread* thread,
                        int64_t value,
                        uint32_t* pc,
                        RawObject** FP,
                        RawObject** SP);

#if defined(DEBUG)
  // Returns true if tracing of executed instructions is enabled.
  bool IsTracingExecution() const;

  // Prints bytecode instruction at given pc for instruction tracing.
  void TraceInstruction(uint32_t* pc) const;
#endif  // defined(DEBUG)

  // Longjmp support for exceptions.
  InterpreterSetjmpBuffer* last_setjmp_buffer() { return last_setjmp_buffer_; }
  void set_last_setjmp_buffer(InterpreterSetjmpBuffer* buffer) {
    last_setjmp_buffer_ = buffer;
  }

  friend class InterpreterSetjmpBuffer;
  DISALLOW_COPY_AND_ASSIGN(Interpreter);
};

}  // namespace dart

#endif  // !defined(DART_PRECOMPILED_RUNTIME)

#endif  // RUNTIME_VM_INTERPRETER_H_
