// 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_SCOPES_H_
|
#define V8_DEBUG_DEBUG_SCOPES_H_
|
|
#include <vector>
|
|
#include "src/debug/debug-frames.h"
|
#include "src/frames.h"
|
|
namespace v8 {
|
namespace internal {
|
|
class ParseInfo;
|
|
// Iterate over the actual scopes visible from a stack frame or from a closure.
|
// The iteration proceeds from the innermost visible nested scope outwards.
|
// All scopes are backed by an actual context except the local scope,
|
// which is inserted "artificially" in the context chain.
|
class ScopeIterator {
|
public:
|
enum ScopeType {
|
ScopeTypeGlobal = 0,
|
ScopeTypeLocal,
|
ScopeTypeWith,
|
ScopeTypeClosure,
|
ScopeTypeCatch,
|
ScopeTypeBlock,
|
ScopeTypeScript,
|
ScopeTypeEval,
|
ScopeTypeModule
|
};
|
|
static const int kScopeDetailsTypeIndex = 0;
|
static const int kScopeDetailsObjectIndex = 1;
|
static const int kScopeDetailsNameIndex = 2;
|
static const int kScopeDetailsStartPositionIndex = 3;
|
static const int kScopeDetailsEndPositionIndex = 4;
|
static const int kScopeDetailsFunctionIndex = 5;
|
static const int kScopeDetailsSize = 6;
|
|
enum Option { DEFAULT, IGNORE_NESTED_SCOPES, COLLECT_NON_LOCALS };
|
|
ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
|
Option options = DEFAULT);
|
|
ScopeIterator(Isolate* isolate, Handle<JSFunction> function);
|
ScopeIterator(Isolate* isolate, Handle<JSGeneratorObject> generator);
|
~ScopeIterator();
|
|
Handle<JSObject> MaterializeScopeDetails();
|
|
// More scopes?
|
bool Done() const { return context_.is_null(); }
|
|
// Move to the next scope.
|
void Next();
|
|
// Restart to the first scope and context.
|
void Restart();
|
|
// Return the type of the current scope.
|
ScopeType Type() const;
|
|
// Indicates which variables should be visited. Either only variables from the
|
// scope that are available on the stack, or all variables.
|
enum class Mode { STACK, ALL };
|
|
// Return the JavaScript object with the content of the current scope.
|
Handle<JSObject> ScopeObject(Mode mode);
|
|
// Returns whether the current scope declares any variables.
|
bool DeclaresLocals(Mode mode) const;
|
|
// Set variable value and return true on success.
|
bool SetVariableValue(Handle<String> variable_name, Handle<Object> new_value);
|
|
// Populate the set with collected non-local variable names.
|
Handle<StringSet> GetNonLocals();
|
|
// Similar to JSFunction::GetName return the function's name or it's inferred
|
// name.
|
Handle<Object> GetFunctionDebugName() const;
|
|
Handle<Script> GetScript() const { return script_; }
|
|
bool HasPositionInfo();
|
int start_position();
|
int end_position();
|
|
#ifdef DEBUG
|
// Debug print of the content of the current scope.
|
void DebugPrint();
|
#endif
|
|
bool InInnerScope() const { return !function_.is_null(); }
|
bool HasContext() const;
|
Handle<Context> CurrentContext() const {
|
DCHECK(HasContext());
|
return context_;
|
}
|
|
private:
|
Isolate* isolate_;
|
ParseInfo* info_ = nullptr;
|
FrameInspector* const frame_inspector_ = nullptr;
|
Handle<JSGeneratorObject> generator_;
|
Handle<JSFunction> function_;
|
Handle<Context> context_;
|
Handle<Script> script_;
|
Handle<StringSet> non_locals_;
|
DeclarationScope* closure_scope_ = nullptr;
|
Scope* start_scope_ = nullptr;
|
Scope* current_scope_ = nullptr;
|
bool seen_script_scope_ = false;
|
|
inline JavaScriptFrame* GetFrame() const {
|
return frame_inspector_->javascript_frame();
|
}
|
|
int GetSourcePosition();
|
|
void TryParseAndRetrieveScopes(ScopeIterator::Option option);
|
|
void RetrieveScopeChain(DeclarationScope* scope);
|
|
void UnwrapEvaluationContext();
|
|
typedef std::function<bool(Handle<String> name, Handle<Object> value)>
|
Visitor;
|
|
Handle<JSObject> WithContextExtension();
|
|
bool SetLocalVariableValue(Handle<String> variable_name,
|
Handle<Object> new_value);
|
bool SetContextVariableValue(Handle<String> variable_name,
|
Handle<Object> new_value);
|
bool SetContextExtensionValue(Handle<String> variable_name,
|
Handle<Object> new_value);
|
bool SetScriptVariableValue(Handle<String> variable_name,
|
Handle<Object> new_value);
|
bool SetModuleVariableValue(Handle<String> variable_name,
|
Handle<Object> new_value);
|
|
// Helper functions.
|
void VisitScope(const Visitor& visitor, Mode mode) const;
|
void VisitLocalScope(const Visitor& visitor, Mode mode) const;
|
void VisitScriptScope(const Visitor& visitor) const;
|
void VisitModuleScope(const Visitor& visitor) const;
|
bool VisitLocals(const Visitor& visitor, Mode mode) const;
|
bool VisitContextLocals(const Visitor& visitor, Handle<ScopeInfo> scope_info,
|
Handle<Context> context) const;
|
|
DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
|
};
|
|
} // namespace internal
|
} // namespace v8
|
|
#endif // V8_DEBUG_DEBUG_SCOPES_H_
|