// 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-table.h"

namespace v8 {
namespace internal {

class FrameInspector;

class DebugEvaluate : public AllStatic {
 public:
  static MaybeHandle<Object> Global(Isolate* isolate, Handle<String> source,
                                    bool throw_on_side_effect);

  // 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);

  // 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> whitelist;
    };

    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_
