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

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: Minor nits 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
Index: src/runtime/runtime-debug.cc
diff --git a/src/runtime/runtime-debug.cc b/src/runtime/runtime-debug.cc
index 28657ee72bcbd3677cdf79e5947e121a5543f0c0..36720111c4057d554791809d8f938a318e3626a1 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);
@@ -986,6 +1009,24 @@ static bool SetClosureVariableValue(Isolate* isolate, Handle<Context> 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(
@@ -1068,6 +1109,7 @@ class ScopeIterator {
public:
enum ScopeType {
ScopeTypeGlobal = 0,
+ ScopeTypeScript,
ScopeTypeLocal,
ScopeTypeWith,
ScopeTypeClosure,
@@ -1084,6 +1126,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());
@@ -1175,6 +1218,7 @@ class ScopeIterator {
inlined_jsframe_index_(0),
function_(function),
context_(function->context()),
+ seen_script_scope_(false),
failed_(false) {
if (function->IsBuiltin()) {
context_ = Handle<Context>();
@@ -1200,8 +1244,17 @@ class ScopeIterator {
return;
}
if (nested_scope_chain_.is_empty()) {
- context_ = Handle<Context>(context_->previous(), isolate_);
+ if (scope_type == ScopeTypeScript) {
+ seen_script_scope_ = true; // Our current context was script context.
+ if (context_->IsScriptContext()) {
+ context_ = Handle<Context>(context_->previous(), isolate_);
+ }
+ CHECK(context_->IsNativeContext());
+ } else {
+ context_ = Handle<Context>(context_->previous(), isolate_);
+ }
} else {
+ seen_script_scope_ = scope_type == ScopeTypeScript;
if (nested_scope_chain_.last()->HasContext()) {
DCHECK(context_->previous() != NULL);
context_ = Handle<Context>(context_->previous(), isolate_);
@@ -1224,8 +1277,8 @@ class ScopeIterator {
DCHECK(context_->IsModuleContext());
return ScopeTypeModule;
case SCRIPT_SCOPE:
- DCHECK(context_->IsNativeContext());
- return ScopeTypeGlobal;
+ DCHECK(context_->IsScriptContext() || context_->IsNativeContext());
yurys 2014/11/14 12:25:32 Why not return ScopeTypeScript only in case contex
+ return ScopeTypeScript;
case WITH_SCOPE:
DCHECK(context_->IsWithContext());
return ScopeTypeWith;
@@ -1241,7 +1294,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,
yurys 2014/11/14 12:25:32 Can you educate me on how this works, I thought th
Dmitry Lomov (no reviews) 2014/11/14 13:56:51 No. I tried to explain this in CL description but
yurys 2014/11/14 15:02:02 Gotcha, thanks for explaining!
+ // fake it.
+ return seen_script_scope_ ? ScopeTypeGlobal : ScopeTypeScript;
}
if (context_->IsFunctionContext()) {
return ScopeTypeClosure;
@@ -1255,6 +1310,9 @@ class ScopeIterator {
if (context_->IsModuleContext()) {
return ScopeTypeModule;
}
+ if (context_->IsScriptContext()) {
+ return ScopeTypeScript;
+ }
DCHECK(context_->IsWithContext());
return ScopeTypeWith;
}
@@ -1265,6 +1323,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);
@@ -1303,6 +1364,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:
// TODO(2399): should we implement it?
break;
@@ -1329,7 +1393,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_;
@@ -1386,6 +1451,15 @@ class ScopeIterator {
}
break;
+ case ScopeIterator::ScopeTypeScript:
+ os << "Script:\n";
+ CurrentContext()
+ ->global_object()
+ ->native_context()
+ ->script_context_table()
+ ->Print(os);
+ break;
+
default:
UNREACHABLE();
}
@@ -1400,6 +1474,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,
@@ -2164,6 +2239,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);

Powered by Google App Engine
This is Rietveld 408576698