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

Unified Diff: src/runtime.cc

Issue 11412310: Issue 2399 part 2: In debugger allow modifying local variable values (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: follow code review Created 8 years 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/frames.cc ('k') | test/mjsunit/debug-set-variable-value.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index 446443148dcf219323317ec5ab40aefd29598706..bc8de56560f8c39c950471dbfa6b9e1bf99da3e3 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -10798,6 +10798,92 @@ static Handle<JSObject> MaterializeLocalScope(
}
+// Set the context local variable value.
+static bool SetContextLocalValue(Isolate* isolate,
+ Handle<ScopeInfo> scope_info,
+ Handle<Context> context,
+ Handle<String> variable_name,
+ Handle<Object> new_value) {
+ for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
+ Handle<String> next_name(scope_info->ContextLocalName(i));
+ if (variable_name->Equals(*next_name)) {
+ VariableMode mode;
+ InitializationFlag init_flag;
+ int context_index =
+ scope_info->ContextSlotIndex(*next_name, &mode, &init_flag);
+ context->set(context_index, *new_value);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+static bool SetLocalVariableValue(Isolate* isolate,
+ JavaScriptFrame* frame,
+ int inlined_jsframe_index,
+ Handle<String> variable_name,
+ Handle<Object> new_value) {
+ if (inlined_jsframe_index != 0 || frame->is_optimized()) {
+ // Optimized frames are not supported.
+ return false;
+ }
+
+ Handle<JSFunction> function(JSFunction::cast(frame->function()));
+ Handle<SharedFunctionInfo> shared(function->shared());
+ Handle<ScopeInfo> scope_info(shared->scope_info());
+
+ // Parameters.
+ for (int i = 0; i < scope_info->ParameterCount(); ++i) {
+ if (scope_info->ParameterName(i)->Equals(*variable_name)) {
+ frame->SetParameterValue(i, *new_value);
+ return true;
+ }
+ }
+
+ // Stack locals.
+ for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
+ if (scope_info->StackLocalName(i)->Equals(*variable_name)) {
+ frame->SetExpression(i, *new_value);
+ return true;
+ }
+ }
+
+ if (scope_info->HasContext()) {
+ // Context locals.
+ Handle<Context> frame_context(Context::cast(frame->context()));
+ Handle<Context> function_context(frame_context->declaration_context());
+ if (SetContextLocalValue(
+ isolate, scope_info, function_context, variable_name, new_value)) {
+ return true;
+ }
+
+ // Function context extension. These are variables introduced by eval.
+ if (function_context->closure() == *function) {
+ if (function_context->has_extension() &&
+ !function_context->IsNativeContext()) {
+ Handle<JSObject> ext(JSObject::cast(function_context->extension()));
+
+ if (ext->HasProperty(*variable_name)) {
+ // We don't expect this to do anything except replacing
+ // property value.
+ SetProperty(isolate,
+ ext,
+ variable_name,
+ new_value,
+ NONE,
+ kNonStrictMode);
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+
// Create a plain JSObject which materializes the closure content for the
// context.
static Handle<JSObject> MaterializeClosure(Isolate* isolate,
@@ -10858,19 +10944,9 @@ static bool SetClosureVariableValue(Isolate* isolate,
Handle<ScopeInfo> scope_info(shared->scope_info());
// Context locals to the context extension.
- for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
- Handle<String> next_name(scope_info->ContextLocalName(i));
- if (variable_name->Equals(*next_name)) {
- VariableMode mode;
- InitializationFlag init_flag;
- int context_index =
- scope_info->ContextSlotIndex(*next_name, &mode, &init_flag);
- if (context_index < 0) {
- return false;
- }
- context->set(context_index, *new_value);
- return true;
- }
+ if (SetContextLocalValue(
+ isolate, scope_info, context, variable_name, new_value)) {
+ return true;
}
// Properties from the function context extension. This will
@@ -10915,6 +10991,20 @@ static Handle<JSObject> MaterializeCatchScope(Isolate* isolate,
}
+static bool SetCatchVariableValue(Isolate* isolate,
+ Handle<Context> context,
+ Handle<String> variable_name,
+ Handle<Object> new_value) {
+ ASSERT(context->IsCatchContext());
+ Handle<String> name(String::cast(context->extension()));
+ if (!name->Equals(*variable_name)) {
+ return false;
+ }
+ context->set(Context::THROWN_OBJECT_INDEX, *new_value);
+ return true;
+}
+
+
// Create a plain JSObject which materializes the block scope for the specified
// block context.
static Handle<JSObject> MaterializeBlockScope(
@@ -11180,13 +11270,13 @@ class ScopeIterator {
case ScopeIterator::ScopeTypeGlobal:
break;
case ScopeIterator::ScopeTypeLocal:
- // TODO(2399): implement.
- break;
+ return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_,
+ variable_name, new_value);
case ScopeIterator::ScopeTypeWith:
break;
case ScopeIterator::ScopeTypeCatch:
- // TODO(2399): implement.
- break;
+ return SetCatchVariableValue(isolate_, CurrentContext(),
+ variable_name, new_value);
case ScopeIterator::ScopeTypeClosure:
return SetClosureVariableValue(isolate_, CurrentContext(),
variable_name, new_value);
« no previous file with comments | « src/frames.cc ('k') | test/mjsunit/debug-set-variable-value.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698