// 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/frames.h"
#include "src/objects.h"
#include "src/objects/string-table.h"

namespace v8 {
namespace internal {

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

  // 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, StackFrame::Id frame_id,
                                   int inlined_jsframe_index,
                                   Handle<String> source,
                                   bool throw_on_side_effect);

  static bool FunctionHasNoSideEffect(Handle<SharedFunctionInfo> info);
  static bool CallbackHasNoSideEffect(Address function_addr);

 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 { return outer_info_; }

   private:
    struct ContextChainElement {
      Handle<ScopeInfo> scope_info;
      Handle<Context> wrapped_context;
      Handle<JSObject> materialized_object;
      Handle<StringSet> whitelist;
    };

    void MaterializeReceiver(Handle<JSObject> target,
                             Handle<Context> local_context,
                             Handle<JSFunction> local_function,
                             Handle<StringSet> non_locals);

    Handle<SharedFunctionInfo> outer_info_;
    Handle<Context> evaluation_context_;
    std::vector<ContextChainElement> context_chain_;
    Isolate* isolate_;
    JavaScriptFrame* frame_;
    int inlined_jsframe_index_;
  };

  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_
