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

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

Issue 726643002: harmony-scoping: Implement debugger support for script scope. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Nit + rebased Created 6 years, 1 month 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/mirror-debugger.js ('k') | test/cctest/test-debug.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime/runtime-debug.cc
diff --git a/src/runtime/runtime-debug.cc b/src/runtime/runtime-debug.cc
index d576dc73a9f41a0f5adcd93874ad2ed5edfa6c5d..68d2f9e4777d0ef30b9e558345ef37039eca26cc 100644
--- a/src/runtime/runtime-debug.cc
+++ b/src/runtime/runtime-debug.cc
@@ -801,6 +801,29 @@ MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext(
}
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScriptScope(
+ Handle<GlobalObject> global) {
+ Isolate* isolate = global->GetIsolate();
+ Handle<ScriptContextTable> script_contexts(
+ global->native_context()->script_context_table());
+
+ Handle<JSObject> script_scope =
+ isolate->factory()->NewJSObject(isolate->object_function());
+
+ for (int context_index = 0; context_index < script_contexts->used();
+ context_index++) {
+ Handle<Context> context =
+ ScriptContextTable::GetContext(script_contexts, context_index);
+ Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
+ if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
+ script_scope)) {
+ return MaybeHandle<JSObject>();
+ }
+ }
+ return script_scope;
+}
+
+
MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope(
Isolate* isolate, JavaScriptFrame* frame, int inlined_jsframe_index) {
FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
@@ -997,6 +1020,24 @@ static bool SetBlockContextVariableValue(Handle<Context> block_context,
}
+static bool SetScriptVariableValue(Handle<Context> context,
+ Handle<String> variable_name,
+ Handle<Object> new_value) {
+ Handle<ScriptContextTable> script_contexts(
+ context->global_object()->native_context()->script_context_table());
+ ScriptContextTable::LookupResult lookup_result;
+ if (ScriptContextTable::Lookup(script_contexts, variable_name,
+ &lookup_result)) {
+ Handle<Context> script_context = ScriptContextTable::GetContext(
+ script_contexts, lookup_result.context_index);
+ script_context->set(lookup_result.slot_index, *new_value);
+ return true;
+ }
+
+ return false;
+}
+
+
// Create a plain JSObject which materializes the scope for the specified
// catch context.
MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
@@ -1084,6 +1125,7 @@ class ScopeIterator {
ScopeTypeClosure,
ScopeTypeCatch,
ScopeTypeBlock,
+ ScopeTypeScript,
ScopeTypeModule
};
@@ -1095,6 +1137,7 @@ class ScopeIterator {
function_(frame->function()),
context_(Context::cast(frame->context())),
nested_scope_chain_(4),
+ seen_script_scope_(false),
failed_(false) {
// Catch the case when the debugger stops in an internal function.
Handle<SharedFunctionInfo> shared_info(function_->shared());
@@ -1186,6 +1229,7 @@ class ScopeIterator {
inlined_jsframe_index_(0),
function_(function),
context_(function->context()),
+ seen_script_scope_(false),
failed_(false) {
if (function->IsBuiltin()) {
context_ = Handle<Context>();
@@ -1210,8 +1254,16 @@ class ScopeIterator {
context_ = Handle<Context>();
return;
}
+ if (scope_type == ScopeTypeScript) seen_script_scope_ = true;
if (nested_scope_chain_.is_empty()) {
- context_ = Handle<Context>(context_->previous(), isolate_);
+ if (scope_type == ScopeTypeScript) {
+ if (context_->IsScriptContext()) {
+ context_ = Handle<Context>(context_->previous(), isolate_);
+ }
+ CHECK(context_->IsNativeContext());
+ } else {
+ context_ = Handle<Context>(context_->previous(), isolate_);
+ }
} else {
if (nested_scope_chain_.last()->HasContext()) {
DCHECK(context_->previous() != NULL);
@@ -1235,8 +1287,8 @@ class ScopeIterator {
DCHECK(context_->IsModuleContext());
return ScopeTypeModule;
case SCRIPT_SCOPE:
- DCHECK(context_->IsNativeContext());
- return ScopeTypeGlobal;
+ DCHECK(context_->IsScriptContext() || context_->IsNativeContext());
+ return ScopeTypeScript;
case WITH_SCOPE:
DCHECK(context_->IsWithContext());
return ScopeTypeWith;
@@ -1252,7 +1304,9 @@ class ScopeIterator {
}
if (context_->IsNativeContext()) {
DCHECK(context_->global_object()->IsGlobalObject());
- return ScopeTypeGlobal;
+ // If we are at the native context and have not yet seen script scope,
+ // fake it.
+ return seen_script_scope_ ? ScopeTypeGlobal : ScopeTypeScript;
}
if (context_->IsFunctionContext()) {
return ScopeTypeClosure;
@@ -1266,6 +1320,9 @@ class ScopeIterator {
if (context_->IsModuleContext()) {
return ScopeTypeModule;
}
+ if (context_->IsScriptContext()) {
+ return ScopeTypeScript;
+ }
DCHECK(context_->IsWithContext());
return ScopeTypeWith;
}
@@ -1276,6 +1333,9 @@ class ScopeIterator {
switch (Type()) {
case ScopeIterator::ScopeTypeGlobal:
return Handle<JSObject>(CurrentContext()->global_object());
+ case ScopeIterator::ScopeTypeScript:
+ return MaterializeScriptScope(
+ Handle<GlobalObject>(CurrentContext()->global_object()));
case ScopeIterator::ScopeTypeLocal:
// Materialize the content of the local scope into a JSObject.
DCHECK(nested_scope_chain_.length() == 1);
@@ -1314,6 +1374,9 @@ class ScopeIterator {
case ScopeIterator::ScopeTypeClosure:
return SetClosureVariableValue(isolate_, CurrentContext(),
variable_name, new_value);
+ case ScopeIterator::ScopeTypeScript:
+ return SetScriptVariableValue(CurrentContext(), variable_name,
+ new_value);
case ScopeIterator::ScopeTypeBlock:
return SetBlockContextVariableValue(CurrentContext(), variable_name,
new_value);
@@ -1340,7 +1403,8 @@ class ScopeIterator {
// be an actual context.
Handle<Context> CurrentContext() {
DCHECK(!failed_);
- if (Type() == ScopeTypeGlobal || nested_scope_chain_.is_empty()) {
+ if (Type() == ScopeTypeGlobal || Type() == ScopeTypeScript ||
+ nested_scope_chain_.is_empty()) {
return context_;
} else if (nested_scope_chain_.last()->HasContext()) {
return context_;
@@ -1397,6 +1461,15 @@ class ScopeIterator {
}
break;
+ case ScopeIterator::ScopeTypeScript:
+ os << "Script:\n";
+ CurrentContext()
+ ->global_object()
+ ->native_context()
+ ->script_context_table()
+ ->Print(os);
+ break;
+
default:
UNREACHABLE();
}
@@ -1411,6 +1484,7 @@ class ScopeIterator {
Handle<JSFunction> function_;
Handle<Context> context_;
List<Handle<ScopeInfo> > nested_scope_chain_;
+ bool seen_script_scope_;
bool failed_;
void RetrieveScopeChain(Scope* scope,
@@ -2175,6 +2249,7 @@ RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
// We iterate to find the function's context. If the function has no
// context-allocated variables, we iterate until we hit the outer context.
while (!function_context->IsFunctionContext() &&
+ !function_context->IsScriptContext() &&
!function_context.is_identical_to(outer_context)) {
inner_context = function_context;
function_context = Handle<Context>(function_context->previous(), isolate);
« no previous file with comments | « src/mirror-debugger.js ('k') | test/cctest/test-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698