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 |