// 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/debug/debug-frames.h"
|
#include "src/debug/debug-scopes.h"
|
#include "src/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, StackFrame::Id 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 bool CallbackHasNoSideEffect(Object* callback_info);
|
static void ApplySideEffectChecks(Handle<BytecodeArray> bytecode_array);
|
|
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_
|