| 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 |