 Chromium Code Reviews
 Chromium Code Reviews Issue 599113002:
  Insert materialized context at the right place in DebugEvaluate.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 599113002:
  Insert materialized context at the right place in DebugEvaluate.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| OLD | NEW | 
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include <stdlib.h> | 5 #include <stdlib.h> | 
| 6 #include <limits> | 6 #include <limits> | 
| 7 | 7 | 
| 8 #include "src/v8.h" | 8 #include "src/v8.h" | 
| 9 | 9 | 
| 10 #include "src/accessors.h" | 10 #include "src/accessors.h" | 
| (...skipping 13037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13048 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); | 13048 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); | 
| 13049 Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction())); | 13049 Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction())); | 
| 13050 | 13050 | 
| 13051 // Traverse the saved contexts chain to find the active context for the | 13051 // Traverse the saved contexts chain to find the active context for the | 
| 13052 // selected frame. | 13052 // selected frame. | 
| 13053 SaveContext* save = FindSavedContextForFrame(isolate, frame); | 13053 SaveContext* save = FindSavedContextForFrame(isolate, frame); | 
| 13054 | 13054 | 
| 13055 SaveContext savex(isolate); | 13055 SaveContext savex(isolate); | 
| 13056 isolate->set_context(*(save->context())); | 13056 isolate->set_context(*(save->context())); | 
| 13057 | 13057 | 
| 13058 // Evaluate on the context of the frame. | |
| 13059 Handle<Context> context(Context::cast(frame_inspector.GetContext())); | |
| 13060 DCHECK(!context.is_null()); | |
| 13061 | |
| 13062 // Materialize stack locals and the arguments object. | 13058 // Materialize stack locals and the arguments object. | 
| 13063 Handle<JSObject> materialized = NewJSObjectWithNullProto(isolate); | 13059 Handle<JSObject> materialized = NewJSObjectWithNullProto(isolate); | 
| 13064 | 13060 | 
| 13065 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 13061 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
| 13066 isolate, materialized, | 13062 isolate, materialized, | 
| 13067 MaterializeStackLocalsWithFrameInspector( | 13063 MaterializeStackLocalsWithFrameInspector( | 
| 13068 isolate, materialized, function, &frame_inspector)); | 13064 isolate, materialized, function, &frame_inspector)); | 
| 13069 | 13065 | 
| 13070 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 13066 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
| 13071 isolate, materialized, | 13067 isolate, materialized, | 
| 13072 MaterializeArgumentsObject(isolate, materialized, function)); | 13068 MaterializeArgumentsObject(isolate, materialized, function)); | 
| 13073 | 13069 | 
| 13074 // Add the materialized object in a with-scope to shadow the stack locals. | 13070 // At this point, the lookup chain may look like this: | 
| 13075 context = isolate->factory()->NewWithContext(function, context, materialized); | 13071 // [inner context] -> [function stack]+[function context] -> [outer context] | 
| 13072 // The function stack is not an actual context, it complements the function | |
| 13073 // context. In order to have the same lookup chain when debug-evaluating, | |
| 13074 // we materialize the stack and insert it into the context chain as a | |
| 13075 // with-context before the function context. | |
| 13076 // [inner context] -> [with context] -> [function context] -> [outer context] | |
| 13077 // Ordering the with-context before the function context forces a dynamic | |
| 13078 // lookup instead of a static lookup that could fail as the scope info is | |
| 13079 // outdated and may expect variables to still be stack-allocated. | |
| 13080 // Afterwards, we write changes to the with-context back to the stack | |
| 13081 // and remove it from the context chain. | |
| 13082 | |
| 13083 Handle<Context> eval_context(Context::cast(frame_inspector.GetContext())); | |
| 13084 DCHECK(!eval_context.is_null()); | |
| 13085 Handle<Context> function_context = eval_context; | |
| 13086 Handle<Context> outer_context(function->context(), isolate); | |
| 13087 Handle<Context> inner_context; | |
| 13088 // We iterate to find the function's context. If the function has no | |
| 13089 // context-allocated variables, we iterate until we hit the outer context. | |
| 13090 while (!function_context->IsFunctionContext() && | |
| 13091 !function_context.is_identical_to(outer_context)) { | |
| 13092 inner_context = function_context; | |
| 13093 function_context = Handle<Context>(function_context->previous(), isolate); | |
| 13094 } | |
| 13095 | |
| 13096 Handle<Context> materialized_context = isolate->factory()->NewWithContext( | |
| 13097 function, function_context, materialized); | |
| 13098 | |
| 13099 if (inner_context.is_null()) { | |
| 13100 // No inner context. The with-context is now inner-most. | |
| 13101 eval_context = materialized_context; | |
| 13102 } else { | |
| 13103 inner_context->set_previous(*materialized_context); | |
| 13104 } | |
| 13076 | 13105 | 
| 13077 Handle<Object> receiver(frame->receiver(), isolate); | 13106 Handle<Object> receiver(frame->receiver(), isolate); | 
| 13107 MaybeHandle<Object> maybe_result = | |
| 13108 DebugEvaluate(isolate, eval_context, context_extension, receiver, source); | |
| 13109 | |
| 13110 // Remove with-context if it was inserted in between. | |
| 13111 if (!inner_context.is_null()) { | |
| 13112 inner_context->set_previous(materialized_context->previous()); | |
| 
aandrey
2014/09/25 06:19:06
nit: inner_context->set_previous(function_context)
 | |
| 13113 } | |
| 13114 | |
| 13078 Handle<Object> result; | 13115 Handle<Object> result; | 
| 13079 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 13116 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result); | 
| 13080 isolate, result, | |
| 13081 DebugEvaluate(isolate, context, context_extension, receiver, source)); | |
| 13082 | 13117 | 
| 13083 // Write back potential changes to materialized stack locals to the stack. | 13118 // Write back potential changes to materialized stack locals to the stack. | 
| 13084 UpdateStackLocalsFromMaterializedObject( | 13119 UpdateStackLocalsFromMaterializedObject( | 
| 13085 isolate, materialized, function, frame, inlined_jsframe_index); | 13120 isolate, materialized, function, frame, inlined_jsframe_index); | 
| 13086 | 13121 | 
| 13087 return *result; | 13122 return *result; | 
| 13088 } | 13123 } | 
| 13089 | 13124 | 
| 13090 | 13125 | 
| 13091 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) { | 13126 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) { | 
| (...skipping 2657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 15749 } | 15784 } | 
| 15750 return NULL; | 15785 return NULL; | 
| 15751 } | 15786 } | 
| 15752 | 15787 | 
| 15753 | 15788 | 
| 15754 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15789 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 
| 15755 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15790 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 
| 15756 } | 15791 } | 
| 15757 | 15792 | 
| 15758 } } // namespace v8::internal | 15793 } } // namespace v8::internal | 
| OLD | NEW |