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

Unified Diff: src/runtime.cc

Issue 11415042: Issue 2399 part 1: In debugger allow modifying local variable values (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: follow codereview 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/runtime.h ('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 de74f2ca6240d69f13fbd45df4d232a833ba3759..0eb6fe3c27d27ec936f92d016ee274bac5c8caf0 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -10806,6 +10806,51 @@ static Handle<JSObject> MaterializeClosure(Isolate* isolate,
}
+// This method copies structure of MaterializeClosure method above.
+static bool SetClosureVariableValue(Isolate* isolate,
+ Handle<Context> context,
+ Handle<String> variable_name,
+ Handle<Object> new_value) {
+ ASSERT(context->IsFunctionContext());
+
+ Handle<SharedFunctionInfo> shared(context->closure()->shared());
+ 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;
+ }
+ }
+
+ // Properties from the function context extension. This will
+ // be variables introduced by eval.
+ if (context->has_extension()) {
+ Handle<JSObject> ext(JSObject::cast(context->extension()));
+ if (ext->HasProperty(*variable_name)) {
+ // We don't expect this to do anything except replacing property value.
+ SetProperty(ext,
+ variable_name,
+ new_value,
+ NONE,
+ kNonStrictMode);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
// Create a plain JSObject which materializes the scope for the specified
// catch context.
static Handle<JSObject> MaterializeCatchScope(Isolate* isolate,
@@ -11081,6 +11126,33 @@ class ScopeIterator {
return Handle<JSObject>();
}
+ bool SetVariableValue(Handle<String> variable_name,
+ Handle<Object> new_value) {
+ ASSERT(!failed_);
+ switch (Type()) {
+ case ScopeIterator::ScopeTypeGlobal:
+ break;
+ case ScopeIterator::ScopeTypeLocal:
+ // TODO(2399): implement.
+ break;
+ case ScopeIterator::ScopeTypeWith:
+ break;
+ case ScopeIterator::ScopeTypeCatch:
+ // TODO(2399): implement.
+ break;
+ case ScopeIterator::ScopeTypeClosure:
+ return SetClosureVariableValue(isolate_, CurrentContext(),
+ variable_name, new_value);
+ case ScopeIterator::ScopeTypeBlock:
+ // TODO(2399): should we implement it?
+ break;
+ case ScopeIterator::ScopeTypeModule:
+ // TODO(2399): should we implement it?
+ break;
+ }
+ return false;
+ }
+
Handle<ScopeInfo> CurrentScopeInfo() {
ASSERT(!failed_);
if (!nested_scope_chain_.is_empty()) {
@@ -11320,6 +11392,64 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeDetails) {
}
+static bool SetScopeVariableValue(ScopeIterator* it, int index,
+ Handle<String> variable_name,
+ Handle<Object> new_value) {
+ for (int n = 0; !it->Done() && n < index; it->Next()) {
+ n++;
+ }
+ if (it->Done()) {
+ return false;
+ }
+ return it->SetVariableValue(variable_name, new_value);
+}
+
+
+// Change variable value in closure or local scope
+// args[0]: number or JsFunction: break id or function
+// args[1]: number: frame index (when arg[0] is break id)
+// args[2]: number: inlined frame index (when arg[0] is break id)
+// args[3]: number: scope index
+// args[4]: string: variable name
+// args[5]: object: new value
+//
+// Return true if success and false otherwise
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScopeVariableValue) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 6);
+
+ // Check arguments.
+ CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
+ CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
+ Handle<Object> new_value = args.at<Object>(5);
+
+ bool res;
+ if (args[0]->IsNumber()) {
+ Object* check;
+ { MaybeObject* maybe_check = Runtime_CheckExecutionState(
+ RUNTIME_ARGUMENTS(isolate, args));
+ if (!maybe_check->ToObject(&check)) return maybe_check;
+ }
+ CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
+ CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
+
+ // Get the frame where the debugging is performed.
+ StackFrame::Id id = UnwrapFrameId(wrapped_id);
+ JavaScriptFrameIterator frame_it(isolate, id);
+ JavaScriptFrame* frame = frame_it.frame();
+
+ ScopeIterator it(isolate, frame, inlined_jsframe_index);
+ res = SetScopeVariableValue(&it, index, variable_name, new_value);
+ } else {
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
+ ScopeIterator it(isolate, fun);
+ res = SetScopeVariableValue(&it, index, variable_name, new_value);
+ }
+
+ return isolate->heap()->ToBoolean(res);
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) {
HandleScope scope(isolate);
ASSERT(args.length() == 0);
« no previous file with comments | « src/runtime.h ('k') | test/mjsunit/debug-set-variable-value.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698