// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_DEBUG_DEBUG_EVALUATE_H_
#define V8_DEBUG_DEBUG_EVALUATE_H_

#include <vector>

#include "src/common/globals.h"
#include "src/debug/debug-frames.h"
#include "src/debug/debug-scopes.h"
#include "src/debug/debug.h"
#include "src/execution/frames.h"
#include "src/objects/objects.h"
#include "src/objects/shared-function-info.h"
#include "src/objects/string-set.h"

namespace v8 {
namespace internal {

class FrameInspector;

class DebugEvaluate : public AllStatic {
 public:
  static MaybeHandle<Object> Global(Isolate* isolate, Handle<String> source,
                                    debug::EvaluateGlobalMode mode,
                                    REPLMode repl_mode = REPLMode::kNo);

  // Evaluate a piece of JavaScript in the context of a stack frame for
  // debugging.  Things that need special attention are:
  // - Parameters and stack-allocated locals need to be materialized.  Altered
  //   values need to be written back to the stack afterwards.
  // - The arguments object needs to materialized.
  static MaybeHandle<Object> Local(Isolate* isolate, StackFrameId frame_id,
                                   int inlined_jsframe_index,
                                   Handle<String> source,
                                   bool throw_on_side_effect);

  static V8_EXPORT MaybeHandle<Object> WebAssembly(
      Handle<WasmInstanceObject> instance, StackFrameId frame_id,
      Handle<String> source, bool throw_on_side_effect);

  // This is used for break-at-entry for builtins and API functions.
  // Evaluate a piece of JavaScript in the native context, but with the
  // materialized arguments object and receiver of the current call.
  static MaybeHandle<Object> WithTopmostArguments(Isolate* isolate,
                                                  Handle<String> source);

  static DebugInfo::SideEffectState FunctionGetSideEffectState(
      Isolate* isolate, Handle<SharedFunctionInfo> info);
  static void ApplySideEffectChecks(Handle<BytecodeArray> bytecode_array);

#ifdef DEBUG
  static void VerifyTransitiveBuiltins(Isolate* isolate);
#endif  // DEBUG

 private:
  // This class builds a context chain for evaluation of expressions
  // in debugger.
  // The scope chain leading up to a breakpoint where evaluation occurs
  // looks like:
  // - [a mix of with, catch and block scopes]
  //    - [function stack + context]
  //      - [outer context]
  // The builder materializes all stack variables into properties of objects;
  // the expression is then evaluated as if it is inside a series of 'with'
  // statements using those objects. To this end, the builder builds a new
  // context chain, based on a scope chain:
  //   - every With and Catch scope begets a cloned context
  //   - Block scope begets one or two contexts:
  //       - if a block has context-allocated varaibles, its context is cloned
  //       - stack locals are materizalized as a With context
  //   - Local scope begets a With context for materizalized locals, chained to
  //     original function context. Original function context is the end of
  //     the chain.
  class ContextBuilder {
   public:
    ContextBuilder(Isolate* isolate, JavaScriptFrame* frame,
                   int inlined_jsframe_index);

    void UpdateValues();

    Handle<Context> evaluation_context() const { return evaluation_context_; }
    Handle<SharedFunctionInfo> outer_info() const;

   private:
    struct ContextChainElement {
      Handle<Context> wrapped_context;
      Handle<JSObject> materialized_object;
      Handle<StringSet> blocklist;
    };

    Handle<Context> evaluation_context_;
    std::vector<ContextChainElement> context_chain_;
    Isolate* isolate_;
    FrameInspector frame_inspector_;
    ScopeIterator scope_iterator_;
  };

  static MaybeHandle<Object> Evaluate(Isolate* isolate,
                                      Handle<SharedFunctionInfo> outer_info,
                                      Handle<Context> context,
                                      Handle<Object> receiver,
                                      Handle<String> source,
                                      bool throw_on_side_effect);
};

}  // namespace internal
}  // namespace v8

#endif  // V8_DEBUG_DEBUG_EVALUATE_H_
