Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Unified Diff: src/debug/debug-scopes.cc

Issue 2898163002: Make non-Module generators only context allocate parameters. (Closed)
Patch Set: Rebase Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/debug/debug-scopes.h ('k') | src/parsing/parser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/debug/debug-scopes.cc
diff --git a/src/debug/debug-scopes.cc b/src/debug/debug-scopes.cc
index 2dfb0af5e88bb0956207af92b65dec4b619e6fb6..b017652c99369ca4eac6bd5652a5ce63262f32a3 100644
--- a/src/debug/debug-scopes.cc
+++ b/src/debug/debug-scopes.cc
@@ -30,16 +30,20 @@ ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
return;
}
- context_ = Handle<Context>::cast(frame_inspector->GetContext());
-
// We should not instantiate a ScopeIterator for wasm frames.
DCHECK(frame_inspector->GetScript()->type() != Script::TYPE_WASM);
+ TryParseAndRetrieveScopes(option);
+}
+
+void ScopeIterator::TryParseAndRetrieveScopes(ScopeIterator::Option option) {
+ context_ = GetContext();
+
// Catch the case when the debugger stops in an internal function.
Handle<JSFunction> function = GetFunction();
Handle<SharedFunctionInfo> shared_info(function->shared());
Handle<ScopeInfo> scope_info(shared_info->scope_info());
- if (shared_info->script()->IsUndefined(isolate)) {
+ if (shared_info->script()->IsUndefined(isolate_)) {
while (context_->closure() == *function) {
context_ = Handle<Context>(context_->previous(), isolate_);
}
@@ -54,7 +58,8 @@ ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
// and include nested scopes into the "fast" iteration case as well.
bool ignore_nested_scopes = (option == IGNORE_NESTED_SCOPES);
bool collect_non_locals = (option == COLLECT_NON_LOCALS);
- if (!ignore_nested_scopes && shared_info->HasDebugInfo()) {
+ if (!ignore_nested_scopes && shared_info->HasDebugInfo() &&
+ frame_inspector_ != nullptr) {
// The source position at return is always the end of the function,
// which is not consistent with the current scope chain. Therefore all
// nested with, catch and block contexts are skipped, and we can only
@@ -109,8 +114,8 @@ ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
// Inner function.
info.reset(new ParseInfo(shared_info));
}
- if (parsing::ParseAny(info.get(), isolate) &&
- Rewriter::Rewrite(info.get(), isolate)) {
+ if (parsing::ParseAny(info.get(), isolate_) &&
+ Rewriter::Rewrite(info.get(), isolate_)) {
DeclarationScope* scope = info->literal()->scope();
if (!ignore_nested_scopes || collect_non_locals) {
CollectNonLocals(info.get(), scope);
@@ -136,7 +141,6 @@ ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
ScopeIterator::ScopeIterator(Isolate* isolate, Handle<JSFunction> function)
: isolate_(isolate),
- frame_inspector_(NULL),
context_(function->context()),
seen_script_scope_(false) {
if (!function->shared()->IsSubjectToDebugging()) context_ = Handle<Context>();
@@ -146,13 +150,14 @@ ScopeIterator::ScopeIterator(Isolate* isolate, Handle<JSFunction> function)
ScopeIterator::ScopeIterator(Isolate* isolate,
Handle<JSGeneratorObject> generator)
: isolate_(isolate),
- frame_inspector_(NULL),
+ generator_(generator),
context_(generator->context()),
seen_script_scope_(false) {
if (!generator->function()->shared()->IsSubjectToDebugging()) {
context_ = Handle<Context>();
+ return;
}
- UnwrapEvaluationContext();
+ TryParseAndRetrieveScopes(DEFAULT);
}
void ScopeIterator::UnwrapEvaluationContext() {
@@ -459,10 +464,36 @@ void ScopeIterator::DebugPrint() {
}
#endif
+inline Handle<Context> ScopeIterator::GetContext() {
+ if (frame_inspector_) {
+ return Handle<Context>::cast(frame_inspector_->GetContext());
+ } else {
+ DCHECK(!generator_.is_null());
+ return handle(generator_->context());
+ }
+}
+
+Handle<JSFunction> ScopeIterator::GetFunction() {
+ if (frame_inspector_) {
+ return frame_inspector_->GetFunction();
+ } else {
+ DCHECK(!generator_.is_null());
+ return handle(generator_->function());
+ }
+}
+
+int ScopeIterator::GetSourcePosition() {
+ if (frame_inspector_) {
+ return frame_inspector_->GetSourcePosition();
+ } else {
+ DCHECK(!generator_.is_null());
+ return generator_->source_position();
+ }
+}
+
void ScopeIterator::RetrieveScopeChain(DeclarationScope* scope) {
DCHECK_NOT_NULL(scope);
- int source_position = frame_inspector_->GetSourcePosition();
- GetNestedScopeChain(isolate_, scope, source_position);
+ GetNestedScopeChain(isolate_, scope, GetSourcePosition());
}
void ScopeIterator::CollectNonLocals(ParseInfo* info, DeclarationScope* scope) {
@@ -490,20 +521,41 @@ MaybeHandle<JSObject> ScopeIterator::MaterializeScriptScope() {
return script_scope;
}
+void ScopeIterator::MaterializeStackLocals(Handle<JSObject> local_scope,
+ Handle<ScopeInfo> scope_info) {
+ if (frame_inspector_) {
+ return frame_inspector_->MaterializeStackLocals(local_scope, scope_info);
+ }
+
+ DCHECK(!generator_.is_null());
+ // Fill all stack locals.
+ Handle<FixedArray> register_file(generator_->register_file());
+ for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
+ Handle<String> name = handle(scope_info->StackLocalName(i));
+ if (ScopeInfo::VariableIsSynthetic(*name)) continue;
+ Handle<Object> value(register_file->get(scope_info->StackLocalIndex(i)),
+ isolate_);
+ // TODO(yangguo): We convert optimized out values to {undefined} when they
+ // are passed to the debugger. Eventually we should handle them somehow.
+ if (value->IsTheHole(isolate_) || value->IsOptimizedOut(isolate_)) {
+ DCHECK(!value.is_identical_to(isolate_->factory()->stale_register()));
+ value = isolate_->factory()->undefined_value();
+ }
+ JSObject::SetOwnPropertyIgnoreAttributes(local_scope, name, value, NONE)
+ .Check();
+ }
+}
MaybeHandle<JSObject> ScopeIterator::MaterializeLocalScope() {
- Handle<JSFunction> function = GetFunction();
+ Handle<JSFunction> function(GetFunction());
+ Handle<SharedFunctionInfo> shared(function->shared());
+ Handle<ScopeInfo> scope_info(shared->scope_info());
Handle<JSObject> local_scope =
isolate_->factory()->NewJSObjectWithNullProto();
- frame_inspector_->MaterializeStackLocals(local_scope, function);
+ MaterializeStackLocals(local_scope, scope_info);
- Handle<Context> frame_context =
- Handle<Context>::cast(frame_inspector_->GetContext());
-
- HandleScope scope(isolate_);
- Handle<SharedFunctionInfo> shared(function->shared());
- Handle<ScopeInfo> scope_info(shared->scope_info());
+ Handle<Context> frame_context = GetContext();
if (!scope_info->HasContext()) return local_scope;
@@ -585,7 +637,7 @@ Handle<JSObject> ScopeIterator::MaterializeInnerScope() {
Handle<Context> context = Handle<Context>::null();
if (!nested_scope_chain_.is_empty()) {
Handle<ScopeInfo> scope_info = nested_scope_chain_.last().scope_info;
- frame_inspector_->MaterializeStackLocals(inner_scope, scope_info);
+ MaterializeStackLocals(inner_scope, scope_info);
if (scope_info->HasContext()) context = CurrentContext();
} else {
context = CurrentContext();
@@ -615,14 +667,19 @@ MaybeHandle<JSObject> ScopeIterator::MaterializeModuleScope() {
}
bool ScopeIterator::SetParameterValue(Handle<ScopeInfo> scope_info,
- JavaScriptFrame* frame,
Handle<String> parameter_name,
Handle<Object> new_value) {
// Setting stack locals of optimized frames is not supported.
- if (frame->is_optimized()) return false;
HandleScope scope(isolate_);
for (int i = 0; i < scope_info->ParameterCount(); ++i) {
if (String::Equals(handle(scope_info->ParameterName(i)), parameter_name)) {
+ // Suspended generators should not get here because all parameters should
+ // be context-allocated.
+ DCHECK_NOT_NULL(frame_inspector_);
+ JavaScriptFrame* frame = GetFrame();
+ if (frame->is_optimized()) {
+ return false;
+ }
frame->SetParameterValue(i, *new_value);
return true;
}
@@ -633,14 +690,24 @@ bool ScopeIterator::SetParameterValue(Handle<ScopeInfo> scope_info,
bool ScopeIterator::SetStackVariableValue(Handle<ScopeInfo> scope_info,
Handle<String> variable_name,
Handle<Object> new_value) {
- if (frame_inspector_ == nullptr) return false;
- JavaScriptFrame* frame = GetFrame();
- // Setting stack locals of optimized frames is not supported.
- if (frame->is_optimized()) return false;
+ // Setting stack locals of optimized frames is not supported. Suspended
+ // generators are supported.
HandleScope scope(isolate_);
for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
- frame->SetExpression(scope_info->StackLocalIndex(i), *new_value);
+ int stack_local_index = scope_info->StackLocalIndex(i);
+ if (frame_inspector_ != nullptr) {
+ // Set the variable on the stack.
+ JavaScriptFrame* frame = GetFrame();
+ if (frame->is_optimized()) return false;
+ frame->SetExpression(stack_local_index, *new_value);
+ } else {
+ // Set the variable in the suspended generator.
+ DCHECK(!generator_.is_null());
+ Handle<FixedArray> register_file(generator_->register_file());
+ DCHECK_LT(stack_local_index, register_file->length());
+ register_file->set(stack_local_index, *new_value);
+ }
return true;
}
}
@@ -683,11 +750,10 @@ bool ScopeIterator::SetContextVariableValue(Handle<ScopeInfo> scope_info,
bool ScopeIterator::SetLocalVariableValue(Handle<String> variable_name,
Handle<Object> new_value) {
- JavaScriptFrame* frame = GetFrame();
- Handle<ScopeInfo> scope_info(frame->function()->shared()->scope_info());
+ Handle<ScopeInfo> scope_info(GetFunction()->shared()->scope_info());
// Parameter might be shadowed in context. Don't stop here.
- bool result = SetParameterValue(scope_info, frame, variable_name, new_value);
+ bool result = SetParameterValue(scope_info, variable_name, new_value);
// Stack locals.
if (SetStackVariableValue(scope_info, variable_name, new_value)) {
@@ -839,7 +905,7 @@ void ScopeIterator::GetNestedScopeChain(Isolate* isolate, Scope* scope,
if (scope->is_function_scope()) {
// Do not collect scopes of nested inner functions inside the current one.
// Nested arrow functions could have the same end positions.
- Handle<JSFunction> function = frame_inspector_->GetFunction();
+ Handle<JSFunction> function = GetFunction();
if (scope->start_position() > function->shared()->start_position() &&
scope->end_position() <= function->shared()->end_position()) {
return;
« no previous file with comments | « src/debug/debug-scopes.h ('k') | src/parsing/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698