#ifndef V8_DEBUG_DEBUG_SCOPES_H_
#define V8_DEBUG_DEBUG_SCOPES_H_
#include "src/debug/debug-frames.h"
#include "src/parsing/parse-info.h"
namespace v8 {
namespace internal {
class JavaScriptFrame;
class ParseInfo;
class V8_EXPORT_PRIVATE 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 class ReparseStrategy {
kFunctionLiteral,
kScriptIfNeeded,
};
ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
ReparseStrategy strategy);
ScopeIterator(Isolate* isolate, DirectHandle<JSFunction> function);
ScopeIterator(Isolate* isolate, Handle<JSGeneratorObject> generator);
~ScopeIterator();
DirectHandle<JSObject> MaterializeScopeDetails();
bool Done() const { return context_.is_null(); }
void Next();
void Restart();
ScopeType Type() const;
enum class Mode { STACK, ALL };
Handle<JSObject> ScopeObject(Mode mode);
bool DeclaresLocals(Mode mode) const;
bool SetVariableValue(Handle<String> variable_name,
DirectHandle<Object> new_value);
bool ClosureScopeHasThisReference() const;
DirectHandle<StringSet> GetLocals() { return locals_; }
DirectHandle<Object> GetFunctionDebugName() const;
DirectHandle<Script> GetScript() const { return script_; }
bool HasPositionInfo();
int start_position();
int end_position();
#ifdef DEBUG
void DebugPrint();
#endif
bool InInnerScope() const { return !function_.is_null(); }
bool HasContext() const;
bool NeedsContext() const;
bool NeedsAndHasContext() const { return NeedsContext() && HasContext(); }
Handle<Context> CurrentContext() const {
DCHECK(HasContext());
return context_;
}
private:
Isolate* isolate_;
std::unique_ptr<ReusableUnoptimizedCompileState> reusable_compile_state_;
std::unique_ptr<ParseInfo> info_;
FrameInspector* const frame_inspector_ = nullptr;
Handle<JSGeneratorObject> generator_;
Handle<JSFunction> function_;
Handle<Context> context_;
Handle<Script> script_;
Handle<StringSet> locals_;
DeclarationScope* closure_scope_ = nullptr;
Scope* start_scope_ = nullptr;
Scope* current_scope_ = nullptr;
bool seen_script_scope_ = false;
bool calculate_blocklists_ = false;
inline JavaScriptFrame* GetFrame() const {
return frame_inspector_->javascript_frame();
}
bool AdvanceOneScope();
void AdvanceOneContext();
void AdvanceScope();
void AdvanceContext();
void CollectLocalsFromCurrentScope();
void MaybeCollectAndStoreLocalBlocklists() const;
int GetSourcePosition() const;
void TryParseAndRetrieveScopes(ReparseStrategy strategy);
void UnwrapEvaluationContext();
using Visitor = std::function<bool(Handle<String> name, Handle<Object> value,
ScopeType scope_type)>;
Handle<JSObject> WithContextExtension();
bool SetLocalVariableValue(DirectHandle<String> variable_name,
DirectHandle<Object> new_value);
bool SetContextVariableValue(DirectHandle<String> variable_name,
DirectHandle<Object> new_value);
bool SetContextExtensionValue(DirectHandle<String> variable_name,
DirectHandle<Object> new_value);
bool SetScriptVariableValue(DirectHandle<String> variable_name,
DirectHandle<Object> new_value);
bool SetModuleVariableValue(DirectHandle<String> variable_name,
DirectHandle<Object> new_value);
void VisitScope(const Visitor& visitor, Mode mode) const;
void VisitLocalScope(const Visitor& visitor, Mode mode,
ScopeType scope_type) const;
void VisitScriptScope(const Visitor& visitor) const;
void VisitModuleScope(const Visitor& visitor) const;
bool VisitLocals(const Visitor& visitor, Mode mode,
ScopeType scope_type) const;
bool VisitContextLocals(const Visitor& visitor,
DirectHandle<ScopeInfo> scope_info,
DirectHandle<Context> context,
ScopeType scope_type) const;
DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
};
}
}
#endif