OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
10 #include "src/debug.h" | 10 #include "src/debug.h" |
(...skipping 2188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2199 CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4); | 2199 CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4); |
2200 CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 5); | 2200 CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 5); |
2201 | 2201 |
2202 // Handle the processing of break. | 2202 // Handle the processing of break. |
2203 DisableBreak disable_break_scope(isolate->debug(), disable_break); | 2203 DisableBreak disable_break_scope(isolate->debug(), disable_break); |
2204 | 2204 |
2205 // Get the frame where the debugging is performed. | 2205 // Get the frame where the debugging is performed. |
2206 StackFrame::Id id = UnwrapFrameId(wrapped_id); | 2206 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
2207 JavaScriptFrameIterator it(isolate, id); | 2207 JavaScriptFrameIterator it(isolate, id); |
2208 JavaScriptFrame* frame = it.frame(); | 2208 JavaScriptFrame* frame = it.frame(); |
2209 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); | |
2210 Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction())); | |
2211 Handle<SharedFunctionInfo> outer_info(function->shared()); | |
2212 | 2209 |
2213 // Traverse the saved contexts chain to find the active context for the | 2210 // Traverse the saved contexts chain to find the active context for the |
2214 // selected frame. | 2211 // selected frame. |
2215 SaveContext* save = FindSavedContextForFrame(isolate, frame); | 2212 SaveContext* save = FindSavedContextForFrame(isolate, frame); |
2216 | 2213 |
2217 SaveContext savex(isolate); | 2214 SaveContext savex(isolate); |
2218 isolate->set_context(*(save->context())); | 2215 isolate->set_context(*(save->context())); |
2219 | 2216 |
2220 // Materialize stack locals and the arguments object. | 2217 // Materialize stack locals and the arguments object. |
2221 Handle<JSObject> materialized = NewJSObjectWithNullProto(isolate); | 2218 Handle<JSObject> materialized; |
| 2219 Handle<JSFunction> function; |
| 2220 Handle<SharedFunctionInfo> outer_info; |
| 2221 Handle<Context> eval_context; |
2222 | 2222 |
2223 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 2223 // We need to limit the lifetime of the FrameInspector because evaluation can |
2224 isolate, materialized, | 2224 // call arbitrary code and only one FrameInspector can be active at a time. |
2225 MaterializeStackLocalsWithFrameInspector(isolate, materialized, function, | 2225 { |
2226 &frame_inspector)); | 2226 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); |
| 2227 materialized = NewJSObjectWithNullProto(isolate); |
| 2228 function = handle(JSFunction::cast(frame_inspector.GetFunction())); |
| 2229 outer_info = handle(function->shared()); |
| 2230 eval_context = handle(Context::cast(frame_inspector.GetContext())); |
2227 | 2231 |
2228 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 2232 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
2229 isolate, materialized, | 2233 isolate, materialized, |
2230 MaterializeArgumentsObject(isolate, materialized, function)); | 2234 MaterializeStackLocalsWithFrameInspector(isolate, materialized, |
| 2235 function, &frame_inspector)); |
| 2236 |
| 2237 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 2238 isolate, materialized, |
| 2239 MaterializeArgumentsObject(isolate, materialized, function)); |
| 2240 } |
2231 | 2241 |
2232 // At this point, the lookup chain may look like this: | 2242 // At this point, the lookup chain may look like this: |
2233 // [inner context] -> [function stack]+[function context] -> [outer context] | 2243 // [inner context] -> [function stack]+[function context] -> [outer context] |
2234 // The function stack is not an actual context, it complements the function | 2244 // The function stack is not an actual context, it complements the function |
2235 // context. In order to have the same lookup chain when debug-evaluating, | 2245 // context. In order to have the same lookup chain when debug-evaluating, |
2236 // we materialize the stack and insert it into the context chain as a | 2246 // we materialize the stack and insert it into the context chain as a |
2237 // with-context before the function context. | 2247 // with-context before the function context. |
2238 // [inner context] -> [with context] -> [function context] -> [outer context] | 2248 // [inner context] -> [with context] -> [function context] -> [outer context] |
2239 // Ordering the with-context before the function context forces a dynamic | 2249 // Ordering the with-context before the function context forces a dynamic |
2240 // lookup instead of a static lookup that could fail as the scope info is | 2250 // lookup instead of a static lookup that could fail as the scope info is |
2241 // outdated and may expect variables to still be stack-allocated. | 2251 // outdated and may expect variables to still be stack-allocated. |
2242 // Afterwards, we write changes to the with-context back to the stack | 2252 // Afterwards, we write changes to the with-context back to the stack |
2243 // and remove it from the context chain. | 2253 // and remove it from the context chain. |
2244 // This could cause lookup failures if debug-evaluate creates a closure that | 2254 // This could cause lookup failures if debug-evaluate creates a closure that |
2245 // uses this temporary context chain. | 2255 // uses this temporary context chain. |
2246 | 2256 |
2247 Handle<Context> eval_context(Context::cast(frame_inspector.GetContext())); | |
2248 DCHECK(!eval_context.is_null()); | 2257 DCHECK(!eval_context.is_null()); |
2249 Handle<Context> function_context = eval_context; | 2258 Handle<Context> function_context = eval_context; |
2250 Handle<Context> outer_context(function->context(), isolate); | 2259 Handle<Context> outer_context(function->context(), isolate); |
2251 Handle<Context> inner_context; | 2260 Handle<Context> inner_context; |
2252 // We iterate to find the function's context. If the function has no | 2261 // We iterate to find the function's context. If the function has no |
2253 // context-allocated variables, we iterate until we hit the outer context. | 2262 // context-allocated variables, we iterate until we hit the outer context. |
2254 while (!function_context->IsFunctionContext() && | 2263 while (!function_context->IsFunctionContext() && |
2255 !function_context->IsScriptContext() && | 2264 !function_context->IsScriptContext() && |
2256 !function_context.is_identical_to(outer_context)) { | 2265 !function_context.is_identical_to(outer_context)) { |
2257 inner_context = function_context; | 2266 inner_context = function_context; |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2835 return Smi::FromInt(isolate->debug()->is_active()); | 2844 return Smi::FromInt(isolate->debug()->is_active()); |
2836 } | 2845 } |
2837 | 2846 |
2838 | 2847 |
2839 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { | 2848 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { |
2840 UNIMPLEMENTED(); | 2849 UNIMPLEMENTED(); |
2841 return NULL; | 2850 return NULL; |
2842 } | 2851 } |
2843 } | 2852 } |
2844 } // namespace v8::internal | 2853 } // namespace v8::internal |
OLD | NEW |