// Copyright (c) 2017, 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_STACK_TRACE_H_
#define RUNTIME_VM_STACK_TRACE_H_

#include <functional>

#include "vm/allocation.h"
#include "vm/flag_list.h"
#include "vm/object.h"
#include "vm/symbols.h"

namespace dart {

// Helper class for finding the closure of the caller.
// This is done via the _AsyncAwaitCompleter which holds a
// FutureResultOrListeners which in turn holds a callback.
class CallerClosureFinder {
 public:
  explicit CallerClosureFinder(Zone* zone);

  ClosurePtr GetCallerInFutureImpl(const Object& future_);

  ClosurePtr FindCallerInAsyncClosure(const Context& receiver_context);

  ClosurePtr FindCallerInAsyncGenClosure(const Context& receiver_context);

  ClosurePtr FindCaller(const Closure& receiver_closure);

  bool IsRunningAsync(const Closure& receiver_closure);

 private:
  Context& receiver_context_;
  Function& receiver_function_;
  Function& parent_function_;

  Object& context_entry_;
  Object& is_sync;
  Object& future_;
  Object& listener_;
  Object& callback_;
  Object& controller_;
  Object& state_;
  Object& var_data_;
  Object& callback_instance_;

  Class& future_impl_class;
  Class& async_await_completer_class;
  Class& future_listener_class;
  Class& async_start_stream_controller_class;
  Class& stream_controller_class;
  Class& async_stream_controller_class;
  Class& controller_subscription_class;
  Class& buffering_stream_subscription_class;
  Class& stream_iterator_class;

  Field& completer_is_sync_field;
  Field& completer_future_field;
  Field& future_result_or_listeners_field;
  Field& callback_field;
  Field& controller_controller_field;
  Field& var_data_field;
  Field& state_field;
  Field& on_data_field;
  Field& state_data_field;
};

class StackTraceUtils : public AllStatic {
 public:
  // Find the async_op closure from the stack frame.
  static ClosurePtr FindClosureInFrame(ObjectPtr* last_object_in_caller,
                                       const Function& function);

  /// Collects all frames on the current stack until an async/async* frame is
  /// hit which has yielded before (i.e. is not in sync-async case).
  ///
  /// From there on finds the closure of the async/async* frame and starts
  /// traversing the listeners:
  ///     while (closure != null) {
  ///       yield_index = closure.context[Context::kAsyncJumpVarIndex]
  ///       pc = closure.function.code.pc_descriptors.LookupPcFromYieldIndex(
  ///           yield_index);
  ///       <emit pc in frame>
  ///       closure = closure.context[Context::kAsyncCompleterVarIndex]._future
  ///           ._resultOrListeners.callback;
  ///     }
  ///
  /// If [on_sync_frames] is non-nullptr, it will be called for every
  /// synchronous frame which is collected.
  static void CollectFramesLazy(
      Thread* thread,
      const GrowableObjectArray& code_array,
      const GrowableObjectArray& pc_offset_array,
      int skip_frames,
      std::function<void(StackFrame*)>* on_sync_frames = nullptr,
      bool* has_async = nullptr);

  /// Counts the number of stack frames.
  /// Skips over the first |skip_frames|.
  /// If |async_function| is not null, stops at the function that has
  /// |async_function| as its parent, and records in 'sync_async_end' whether
  /// |async_function| was called synchronously.
  static intptr_t CountFrames(Thread* thread,
                              int skip_frames,
                              const Function& async_function,
                              bool* sync_async_end);

  /// Collects |count| frames into |code_array| and |pc_offset_array|.
  /// Writing begins at |array_offset|.
  /// Skips over the first |skip_frames|.
  /// Returns the number of frames collected.
  static intptr_t CollectFrames(Thread* thread,
                                const Array& code_array,
                                const Array& pc_offset_array,
                                intptr_t array_offset,
                                intptr_t count,
                                int skip_frames);

  /// If |thread| has no async_stack_trace, does nothing.
  /// Populates |async_function| with the top function of the async stack
  /// trace. Populates |async_stack_trace|, |async_code_array|, and
  /// |async_pc_offset_array| with the thread's async_stack_trace.
  /// Returns the length of the asynchronous stack trace.
  static intptr_t ExtractAsyncStackTraceInfo(Thread* thread,
                                             Function* async_function,
                                             StackTrace* async_stack_trace,
                                             Array* async_code_array,
                                             Array* async_pc_offset_array);

  // The number of frames involved in a "sync-async" gap: a synchronous initial
  // invocation of an asynchronous function. See CheckAndSkipAsync.
  static constexpr intptr_t kSyncAsyncFrameGap = 2;

  // A synchronous invocation of an async function involves the following
  // frames:
  //   <async function>__<anonymous_closure>    (0)
  //   _Closure.call                            (1)
  //   _AsyncAwaitCompleter.start               (2)
  //   <async_function>                         (3)
  //
  // Alternatively, for optimized frames, we may see:
  //   <async function>__<anonymous_closure>    (0)
  //   _AsyncAwaitCompleter.start               (1)
  //   <async_function>                         (2)
  static bool CheckAndSkipAsync(int* skip_sync_async_frames_count,
                                const String& function_name) {
    ASSERT(*skip_sync_async_frames_count > 0);
    // Make sure any function objects for methods used here are marked for
    // retention by the precompiler, even if otherwise not needed at runtime.
    //
    // _AsyncAwaitCompleter.start is marked with the vm:entry-point pragma.
    if (function_name.Equals(Symbols::_AsyncAwaitCompleterStart())) {
      *skip_sync_async_frames_count = 0;
      return true;
    }
    // _Closure.call is explicitly checked in Precompiler::MustRetainFunction.
    if (function_name.Equals(Symbols::_ClosureCall()) &&
        *skip_sync_async_frames_count == 2) {
      (*skip_sync_async_frames_count)--;
      return true;
    }
    return false;
  }
};

}  // namespace dart

#endif  // RUNTIME_VM_STACK_TRACE_H_
