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 2235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2246 | 2246 |
2247 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 2247 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
2248 isolate, materialized, | 2248 isolate, materialized, |
2249 MaterializeArgumentsObject(isolate, materialized, function)); | 2249 MaterializeArgumentsObject(isolate, materialized, function)); |
2250 } | 2250 } |
2251 | 2251 |
2252 // At this point, the lookup chain may look like this: | 2252 // At this point, the lookup chain may look like this: |
2253 // [inner context] -> [function stack]+[function context] -> [outer context] | 2253 // [inner context] -> [function stack]+[function context] -> [outer context] |
2254 // The function stack is not an actual context, it complements the function | 2254 // The function stack is not an actual context, it complements the function |
2255 // context. In order to have the same lookup chain when debug-evaluating, | 2255 // context. In order to have the same lookup chain when debug-evaluating, |
2256 // we materialize the stack and insert it into the context chain as a | 2256 // we: |
2257 // with-context before the function context. | 2257 // - clone inner context |
2258 // [inner context] -> [with context] -> [function context] -> [outer context] | 2258 // - materialize the stack and insert it into the context chain as a |
| 2259 // with-context before the function context. |
| 2260 // [inner context clone] -> [with context] -> [function context] -> |
| 2261 // [outer context] |
2259 // Ordering the with-context before the function context forces a dynamic | 2262 // Ordering the with-context before the function context forces a dynamic |
2260 // lookup instead of a static lookup that could fail as the scope info is | 2263 // lookup instead of a static lookup that could fail as the scope info is |
2261 // outdated and may expect variables to still be stack-allocated. | 2264 // outdated and may expect variables to still be stack-allocated. |
2262 // Afterwards, we write changes to the with-context back to the stack | 2265 // Afterwards, we write changes to the with-context back to the stack, and |
2263 // and remove it from the context chain. | 2266 // write changes in cloned contexts back to original contexts. |
2264 // This could cause lookup failures if debug-evaluate creates a closure that | |
2265 // uses this temporary context chain. | |
2266 | 2267 |
2267 DCHECK(!eval_context.is_null()); | 2268 DCHECK(!eval_context.is_null()); |
2268 Handle<Context> function_context = eval_context; | 2269 Handle<Context> function_context = eval_context; |
2269 Handle<Context> outer_context(function->context(), isolate); | 2270 Handle<Context> outer_context(function->context(), isolate); |
2270 Handle<Context> inner_context; | 2271 Handle<Context> inner_context; |
2271 // We iterate to find the function's context. If the function has no | 2272 Handle<Context> innermost_context; |
2272 // context-allocated variables, we iterate until we hit the outer context. | 2273 |
| 2274 // We iterate to find the function's context, cloning until we hit it. |
| 2275 // If the function has no context-allocated variables, we iterate until |
| 2276 // we hit the outer context. |
2273 while (!function_context->IsFunctionContext() && | 2277 while (!function_context->IsFunctionContext() && |
2274 !function_context->IsScriptContext() && | 2278 !function_context->IsScriptContext() && |
2275 !function_context.is_identical_to(outer_context)) { | 2279 !function_context.is_identical_to(outer_context)) { |
2276 inner_context = function_context; | 2280 Handle<Context> clone = Handle<Context>::cast( |
| 2281 FixedArray::CopySize(function_context, function_context->length())); |
| 2282 if (!inner_context.is_null()) { |
| 2283 inner_context->set_previous(*clone); |
| 2284 } else { |
| 2285 innermost_context = clone; |
| 2286 } |
| 2287 inner_context = clone; |
2277 function_context = Handle<Context>(function_context->previous(), isolate); | 2288 function_context = Handle<Context>(function_context->previous(), isolate); |
2278 } | 2289 } |
2279 | 2290 |
2280 Handle<Context> materialized_context = isolate->factory()->NewWithContext( | 2291 Handle<Context> materialized_context = isolate->factory()->NewWithContext( |
2281 function, function_context, materialized); | 2292 function, function_context, materialized); |
2282 | 2293 |
2283 if (inner_context.is_null()) { | 2294 if (inner_context.is_null()) { |
2284 // No inner context. The with-context is now inner-most. | 2295 // No inner context. The with-context is now inner-most. |
2285 eval_context = materialized_context; | 2296 innermost_context = materialized_context; |
2286 } else { | 2297 } else { |
2287 inner_context->set_previous(*materialized_context); | 2298 inner_context->set_previous(*materialized_context); |
2288 } | 2299 } |
2289 | 2300 |
2290 Handle<Object> receiver(frame->receiver(), isolate); | 2301 Handle<Object> receiver(frame->receiver(), isolate); |
2291 MaybeHandle<Object> maybe_result = DebugEvaluate( | 2302 MaybeHandle<Object> maybe_result = |
2292 isolate, outer_info, eval_context, context_extension, receiver, source); | 2303 DebugEvaluate(isolate, outer_info, innermost_context, context_extension, |
2293 | 2304 receiver, source); |
2294 // Remove with-context if it was inserted in between. | |
2295 if (!inner_context.is_null()) inner_context->set_previous(*function_context); | |
2296 | 2305 |
2297 Handle<Object> result; | 2306 Handle<Object> result; |
2298 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result); | 2307 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result); |
2299 | 2308 |
2300 // Write back potential changes to materialized stack locals to the stack. | 2309 // Write back potential changes to materialized stack locals to the stack. |
2301 UpdateStackLocalsFromMaterializedObject(isolate, materialized, function, | 2310 UpdateStackLocalsFromMaterializedObject(isolate, materialized, function, |
2302 frame, inlined_jsframe_index); | 2311 frame, inlined_jsframe_index); |
2303 | 2312 |
| 2313 while (!innermost_context.is_identical_to(materialized_context)) { |
| 2314 DCHECK(eval_context->map() == innermost_context->map()); |
| 2315 innermost_context->CopyTo( |
| 2316 Context::MIN_CONTEXT_SLOTS, *eval_context, Context::MIN_CONTEXT_SLOTS, |
| 2317 innermost_context->length() - Context::MIN_CONTEXT_SLOTS); |
| 2318 innermost_context = handle(innermost_context->previous(), isolate); |
| 2319 eval_context = handle(eval_context->previous(), isolate); |
| 2320 } |
| 2321 |
2304 return *result; | 2322 return *result; |
2305 } | 2323 } |
2306 | 2324 |
2307 | 2325 |
2308 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) { | 2326 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) { |
2309 HandleScope scope(isolate); | 2327 HandleScope scope(isolate); |
2310 | 2328 |
2311 // Check the execution state and decode arguments frame and source to be | 2329 // Check the execution state and decode arguments frame and source to be |
2312 // evaluated. | 2330 // evaluated. |
2313 DCHECK(args.length() == 4); | 2331 DCHECK(args.length() == 4); |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2819 return Smi::FromInt(isolate->debug()->is_active()); | 2837 return Smi::FromInt(isolate->debug()->is_active()); |
2820 } | 2838 } |
2821 | 2839 |
2822 | 2840 |
2823 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { | 2841 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { |
2824 UNIMPLEMENTED(); | 2842 UNIMPLEMENTED(); |
2825 return NULL; | 2843 return NULL; |
2826 } | 2844 } |
2827 } | 2845 } |
2828 } // namespace v8::internal | 2846 } // namespace v8::internal |
OLD | NEW |