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 12578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12589 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); | 12589 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); |
12590 Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction())); | 12590 Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction())); |
12591 | 12591 |
12592 // Traverse the saved contexts chain to find the active context for the | 12592 // Traverse the saved contexts chain to find the active context for the |
12593 // selected frame. | 12593 // selected frame. |
12594 SaveContext* save = FindSavedContextForFrame(isolate, frame); | 12594 SaveContext* save = FindSavedContextForFrame(isolate, frame); |
12595 | 12595 |
12596 SaveContext savex(isolate); | 12596 SaveContext savex(isolate); |
12597 isolate->set_context(*(save->context())); | 12597 isolate->set_context(*(save->context())); |
12598 | 12598 |
12599 // Evaluate on the context of the frame. | |
12600 Handle<Context> context(Context::cast(frame_inspector.GetContext())); | |
12601 DCHECK(!context.is_null()); | |
12602 | |
12603 // Materialize stack locals and the arguments object. | 12599 // Materialize stack locals and the arguments object. |
12604 Handle<JSObject> materialized = NewJSObjectWithNullProto(isolate); | 12600 Handle<JSObject> materialized = NewJSObjectWithNullProto(isolate); |
12605 | 12601 |
12606 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 12602 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
12607 isolate, materialized, | 12603 isolate, materialized, |
12608 MaterializeStackLocalsWithFrameInspector(isolate, materialized, function, | 12604 MaterializeStackLocalsWithFrameInspector(isolate, materialized, function, |
12609 &frame_inspector)); | 12605 &frame_inspector)); |
12610 | 12606 |
12611 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 12607 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
12612 isolate, materialized, | 12608 isolate, materialized, |
12613 MaterializeArgumentsObject(isolate, materialized, function)); | 12609 MaterializeArgumentsObject(isolate, materialized, function)); |
12614 | 12610 |
12615 // Add the materialized object in a with-scope to shadow the stack locals. | 12611 // At this point, the lookup chain may look like this: |
12616 context = isolate->factory()->NewWithContext(function, context, materialized); | 12612 // [inner context] -> [function stack]+[function context] -> [outer context] |
| 12613 // The function stack is not an actual context, it complements the function |
| 12614 // context. In order to have the same lookup chain when debug-evaluating, |
| 12615 // we materialize the stack and insert it into the context chain as a |
| 12616 // with-context before the function context. |
| 12617 // [inner context] -> [with context] -> [function context] -> [outer context] |
| 12618 // Ordering the with-context before the function context forces a dynamic |
| 12619 // lookup instead of a static lookup that could fail as the scope info is |
| 12620 // outdated and may expect variables to still be stack-allocated. |
| 12621 // Afterwards, we write changes to the with-context back to the stack |
| 12622 // and remove it from the context chain. |
| 12623 // This could cause lookup failures if debug-evaluate creates a closure that |
| 12624 // uses this temporary context chain. |
| 12625 |
| 12626 Handle<Context> eval_context(Context::cast(frame_inspector.GetContext())); |
| 12627 DCHECK(!eval_context.is_null()); |
| 12628 Handle<Context> function_context = eval_context; |
| 12629 Handle<Context> outer_context(function->context(), isolate); |
| 12630 Handle<Context> inner_context; |
| 12631 // We iterate to find the function's context. If the function has no |
| 12632 // context-allocated variables, we iterate until we hit the outer context. |
| 12633 while (!function_context->IsFunctionContext() && |
| 12634 !function_context.is_identical_to(outer_context)) { |
| 12635 inner_context = function_context; |
| 12636 function_context = Handle<Context>(function_context->previous(), isolate); |
| 12637 } |
| 12638 |
| 12639 Handle<Context> materialized_context = isolate->factory()->NewWithContext( |
| 12640 function, function_context, materialized); |
| 12641 |
| 12642 if (inner_context.is_null()) { |
| 12643 // No inner context. The with-context is now inner-most. |
| 12644 eval_context = materialized_context; |
| 12645 } else { |
| 12646 inner_context->set_previous(*materialized_context); |
| 12647 } |
12617 | 12648 |
12618 Handle<Object> receiver(frame->receiver(), isolate); | 12649 Handle<Object> receiver(frame->receiver(), isolate); |
| 12650 MaybeHandle<Object> maybe_result = |
| 12651 DebugEvaluate(isolate, eval_context, context_extension, receiver, source); |
| 12652 |
| 12653 // Remove with-context if it was inserted in between. |
| 12654 if (!inner_context.is_null()) inner_context->set_previous(*function_context); |
| 12655 |
12619 Handle<Object> result; | 12656 Handle<Object> result; |
12620 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 12657 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result); |
12621 isolate, result, | |
12622 DebugEvaluate(isolate, context, context_extension, receiver, source)); | |
12623 | 12658 |
12624 // Write back potential changes to materialized stack locals to the stack. | 12659 // Write back potential changes to materialized stack locals to the stack. |
12625 UpdateStackLocalsFromMaterializedObject(isolate, materialized, function, | 12660 UpdateStackLocalsFromMaterializedObject(isolate, materialized, function, |
12626 frame, inlined_jsframe_index); | 12661 frame, inlined_jsframe_index); |
12627 | 12662 |
12628 return *result; | 12663 return *result; |
12629 } | 12664 } |
12630 | 12665 |
12631 | 12666 |
12632 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) { | 12667 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) { |
(...skipping 1904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14537 } | 14572 } |
14538 return NULL; | 14573 return NULL; |
14539 } | 14574 } |
14540 | 14575 |
14541 | 14576 |
14542 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 14577 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
14543 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 14578 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
14544 } | 14579 } |
14545 } | 14580 } |
14546 } // namespace v8::internal | 14581 } // namespace v8::internal |
OLD | NEW |