OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 8296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8307 isolate->heap()->AllocateCatchContext(function, | 8307 isolate->heap()->AllocateCatchContext(function, |
8308 isolate->context(), | 8308 isolate->context(), |
8309 name, | 8309 name, |
8310 thrown_object); | 8310 thrown_object); |
8311 if (!maybe_context->To(&context)) return maybe_context; | 8311 if (!maybe_context->To(&context)) return maybe_context; |
8312 isolate->set_context(context); | 8312 isolate->set_context(context); |
8313 return context; | 8313 return context; |
8314 } | 8314 } |
8315 | 8315 |
8316 | 8316 |
| 8317 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushBlockContext) { |
| 8318 NoHandleAllocation ha; |
| 8319 ASSERT(args.length() == 2); |
| 8320 SerializedScopeInfo* scope_info = SerializedScopeInfo::cast(args[0]); |
| 8321 JSFunction* function; |
| 8322 if (args[1]->IsSmi()) { |
| 8323 // A smi sentinel indicates a context nested inside global code rather |
| 8324 // than some function. There is a canonical empty function that can be |
| 8325 // gotten from the global context. |
| 8326 function = isolate->context()->global_context()->closure(); |
| 8327 } else { |
| 8328 function = JSFunction::cast(args[1]); |
| 8329 } |
| 8330 Context* context; |
| 8331 MaybeObject* maybe_context = |
| 8332 isolate->heap()->AllocateBlockContext(function, |
| 8333 isolate->context(), |
| 8334 scope_info); |
| 8335 if (!maybe_context->To(&context)) return maybe_context; |
| 8336 isolate->set_context(context); |
| 8337 return context; |
| 8338 } |
| 8339 |
| 8340 |
8317 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) { | 8341 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) { |
8318 HandleScope scope(isolate); | 8342 HandleScope scope(isolate); |
8319 ASSERT(args.length() == 2); | 8343 ASSERT(args.length() == 2); |
8320 | 8344 |
8321 CONVERT_ARG_CHECKED(Context, context, 0); | 8345 CONVERT_ARG_CHECKED(Context, context, 0); |
8322 CONVERT_ARG_CHECKED(String, name, 1); | 8346 CONVERT_ARG_CHECKED(String, name, 1); |
8323 | 8347 |
8324 int index; | 8348 int index; |
8325 PropertyAttributes attributes; | 8349 PropertyAttributes attributes; |
8326 ContextLookupFlags flags = FOLLOW_CHAINS; | 8350 ContextLookupFlags flags = FOLLOW_CHAINS; |
(...skipping 2305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10632 Handle<JSObject> catch_scope = | 10656 Handle<JSObject> catch_scope = |
10633 isolate->factory()->NewJSObject(isolate->object_function()); | 10657 isolate->factory()->NewJSObject(isolate->object_function()); |
10634 RETURN_IF_EMPTY_HANDLE_VALUE( | 10658 RETURN_IF_EMPTY_HANDLE_VALUE( |
10635 isolate, | 10659 isolate, |
10636 SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode), | 10660 SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode), |
10637 Handle<JSObject>()); | 10661 Handle<JSObject>()); |
10638 return catch_scope; | 10662 return catch_scope; |
10639 } | 10663 } |
10640 | 10664 |
10641 | 10665 |
| 10666 // Create a plain JSObject which materializes the block scope for the specified |
| 10667 // block context. |
| 10668 static Handle<JSObject> MaterializeBlockScope( |
| 10669 Isolate* isolate, |
| 10670 Handle<Context> context) { |
| 10671 ASSERT(context->IsBlockContext()); |
| 10672 Handle<SerializedScopeInfo> serialized_scope_info( |
| 10673 SerializedScopeInfo::cast(context->extension())); |
| 10674 ScopeInfo<> scope_info(*serialized_scope_info); |
| 10675 |
| 10676 // Allocate and initialize a JSObject with all the arguments, stack locals |
| 10677 // heap locals and extension properties of the debugged function. |
| 10678 Handle<JSObject> block_scope = |
| 10679 isolate->factory()->NewJSObject(isolate->object_function()); |
| 10680 |
| 10681 // Fill all context locals. |
| 10682 if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) { |
| 10683 if (!CopyContextLocalsToScopeObject(isolate, |
| 10684 serialized_scope_info, scope_info, |
| 10685 context, block_scope)) { |
| 10686 return Handle<JSObject>(); |
| 10687 } |
| 10688 } |
| 10689 |
| 10690 return block_scope; |
| 10691 } |
| 10692 |
| 10693 |
10642 // Iterate over the actual scopes visible from a stack frame. All scopes are | 10694 // Iterate over the actual scopes visible from a stack frame. All scopes are |
10643 // backed by an actual context except the local scope, which is inserted | 10695 // backed by an actual context except the local scope, which is inserted |
10644 // "artifically" in the context chain. | 10696 // "artifically" in the context chain. |
10645 class ScopeIterator { | 10697 class ScopeIterator { |
10646 public: | 10698 public: |
10647 enum ScopeType { | 10699 enum ScopeType { |
10648 ScopeTypeGlobal = 0, | 10700 ScopeTypeGlobal = 0, |
10649 ScopeTypeLocal, | 10701 ScopeTypeLocal, |
10650 ScopeTypeWith, | 10702 ScopeTypeWith, |
10651 ScopeTypeClosure, | 10703 ScopeTypeClosure, |
10652 ScopeTypeCatch | 10704 ScopeTypeCatch, |
| 10705 ScopeTypeBlock |
10653 }; | 10706 }; |
10654 | 10707 |
10655 ScopeIterator(Isolate* isolate, | 10708 ScopeIterator(Isolate* isolate, |
10656 JavaScriptFrame* frame, | 10709 JavaScriptFrame* frame, |
10657 int inlined_frame_index) | 10710 int inlined_frame_index) |
10658 : isolate_(isolate), | 10711 : isolate_(isolate), |
10659 frame_(frame), | 10712 frame_(frame), |
10660 inlined_frame_index_(inlined_frame_index), | 10713 inlined_frame_index_(inlined_frame_index), |
10661 function_(JSFunction::cast(frame->function())), | 10714 function_(JSFunction::cast(frame->function())), |
10662 context_(Context::cast(frame->context())), | 10715 context_(Context::cast(frame->context())), |
10663 local_done_(false), | 10716 local_done_(false), |
10664 at_local_(false) { | 10717 at_local_(false) { |
10665 | 10718 |
10666 // Check whether the first scope is actually a local scope. | 10719 // Check whether the first scope is actually a local scope. |
10667 if (context_->IsGlobalContext()) { | 10720 if (context_->IsGlobalContext()) { |
10668 // If there is a stack slot for .result then this local scope has been | 10721 // If there is a stack slot for .result then this local scope has been |
10669 // created for evaluating top level code and it is not a real local scope. | 10722 // created for evaluating top level code and it is not a real local scope. |
10670 // Checking for the existence of .result seems fragile, but the scope info | 10723 // Checking for the existence of .result seems fragile, but the scope info |
10671 // saved with the code object does not otherwise have that information. | 10724 // saved with the code object does not otherwise have that information. |
10672 int index = function_->shared()->scope_info()-> | 10725 int index = function_->shared()->scope_info()-> |
10673 StackSlotIndex(isolate_->heap()->result_symbol()); | 10726 StackSlotIndex(isolate_->heap()->result_symbol()); |
10674 at_local_ = index < 0; | 10727 at_local_ = index < 0; |
10675 } else if (context_->IsFunctionContext()) { | 10728 } else if (context_->IsFunctionContext()) { |
10676 at_local_ = true; | 10729 at_local_ = true; |
10677 } else if (context_->closure() != *function_) { | 10730 } else if (context_->closure() != *function_) { |
10678 // The context_ is a with or catch block from the outer function. | 10731 // The context_ is a block or with or catch block from the outer function. |
10679 ASSERT(context_->IsWithContext() || context_->IsCatchContext()); | 10732 ASSERT(context_->IsWithContext() || |
| 10733 context_->IsCatchContext() || |
| 10734 context_->IsBlockContext()); |
10680 at_local_ = true; | 10735 at_local_ = true; |
10681 } | 10736 } |
10682 } | 10737 } |
10683 | 10738 |
10684 // More scopes? | 10739 // More scopes? |
10685 bool Done() { return context_.is_null(); } | 10740 bool Done() { return context_.is_null(); } |
10686 | 10741 |
10687 // Move to the next scope. | 10742 // Move to the next scope. |
10688 void Next() { | 10743 void Next() { |
10689 // If at a local scope mark the local scope as passed. | 10744 // If at a local scope mark the local scope as passed. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10724 if (context_->IsGlobalContext()) { | 10779 if (context_->IsGlobalContext()) { |
10725 ASSERT(context_->global()->IsGlobalObject()); | 10780 ASSERT(context_->global()->IsGlobalObject()); |
10726 return ScopeTypeGlobal; | 10781 return ScopeTypeGlobal; |
10727 } | 10782 } |
10728 if (context_->IsFunctionContext()) { | 10783 if (context_->IsFunctionContext()) { |
10729 return ScopeTypeClosure; | 10784 return ScopeTypeClosure; |
10730 } | 10785 } |
10731 if (context_->IsCatchContext()) { | 10786 if (context_->IsCatchContext()) { |
10732 return ScopeTypeCatch; | 10787 return ScopeTypeCatch; |
10733 } | 10788 } |
| 10789 if (context_->IsBlockContext()) { |
| 10790 return ScopeTypeBlock; |
| 10791 } |
10734 ASSERT(context_->IsWithContext()); | 10792 ASSERT(context_->IsWithContext()); |
10735 return ScopeTypeWith; | 10793 return ScopeTypeWith; |
10736 } | 10794 } |
10737 | 10795 |
10738 // Return the JavaScript object with the content of the current scope. | 10796 // Return the JavaScript object with the content of the current scope. |
10739 Handle<JSObject> ScopeObject() { | 10797 Handle<JSObject> ScopeObject() { |
10740 switch (Type()) { | 10798 switch (Type()) { |
10741 case ScopeIterator::ScopeTypeGlobal: | 10799 case ScopeIterator::ScopeTypeGlobal: |
10742 return Handle<JSObject>(CurrentContext()->global()); | 10800 return Handle<JSObject>(CurrentContext()->global()); |
10743 case ScopeIterator::ScopeTypeLocal: | 10801 case ScopeIterator::ScopeTypeLocal: |
10744 // Materialize the content of the local scope into a JSObject. | 10802 // Materialize the content of the local scope into a JSObject. |
10745 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); | 10803 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); |
10746 case ScopeIterator::ScopeTypeWith: | 10804 case ScopeIterator::ScopeTypeWith: |
10747 // Return the with object. | 10805 // Return the with object. |
10748 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); | 10806 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); |
10749 case ScopeIterator::ScopeTypeCatch: | 10807 case ScopeIterator::ScopeTypeCatch: |
10750 return MaterializeCatchScope(isolate_, CurrentContext()); | 10808 return MaterializeCatchScope(isolate_, CurrentContext()); |
10751 case ScopeIterator::ScopeTypeClosure: | 10809 case ScopeIterator::ScopeTypeClosure: |
10752 // Materialize the content of the closure scope into a JSObject. | 10810 // Materialize the content of the closure scope into a JSObject. |
10753 return MaterializeClosure(isolate_, CurrentContext()); | 10811 return MaterializeClosure(isolate_, CurrentContext()); |
| 10812 case ScopeIterator::ScopeTypeBlock: |
| 10813 return MaterializeBlockScope(isolate_, CurrentContext()); |
10754 } | 10814 } |
10755 UNREACHABLE(); | 10815 UNREACHABLE(); |
10756 return Handle<JSObject>(); | 10816 return Handle<JSObject>(); |
10757 } | 10817 } |
10758 | 10818 |
10759 // Return the context for this scope. For the local context there might not | 10819 // Return the context for this scope. For the local context there might not |
10760 // be an actual context. | 10820 // be an actual context. |
10761 Handle<Context> CurrentContext() { | 10821 Handle<Context> CurrentContext() { |
10762 if (at_local_ && context_->closure() != *function_) { | 10822 if (at_local_ && context_->closure() != *function_) { |
10763 return Handle<Context>(); | 10823 return Handle<Context>(); |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11300 CopyWithContextChain(isolate, function, previous, base); | 11360 CopyWithContextChain(isolate, function, previous, base); |
11301 Handle<Context> new_current; | 11361 Handle<Context> new_current; |
11302 if (current->IsCatchContext()) { | 11362 if (current->IsCatchContext()) { |
11303 Handle<String> name(String::cast(current->extension())); | 11363 Handle<String> name(String::cast(current->extension())); |
11304 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); | 11364 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); |
11305 new_current = | 11365 new_current = |
11306 isolate->factory()->NewCatchContext(function, | 11366 isolate->factory()->NewCatchContext(function, |
11307 new_previous, | 11367 new_previous, |
11308 name, | 11368 name, |
11309 thrown_object); | 11369 thrown_object); |
| 11370 } else if (current->IsBlockContext()) { |
| 11371 Handle<SerializedScopeInfo> scope_info( |
| 11372 SerializedScopeInfo::cast(current->extension())); |
| 11373 new_current = |
| 11374 isolate->factory()->NewBlockContext(function, new_previous, scope_info); |
11310 } else { | 11375 } else { |
| 11376 ASSERT(current->IsWithContext()); |
11311 Handle<JSObject> extension(JSObject::cast(current->extension())); | 11377 Handle<JSObject> extension(JSObject::cast(current->extension())); |
11312 new_current = | 11378 new_current = |
11313 isolate->factory()->NewWithContext(function, new_previous, extension); | 11379 isolate->factory()->NewWithContext(function, new_previous, extension); |
11314 } | 11380 } |
11315 return scope.CloseAndEscape(new_current); | 11381 return scope.CloseAndEscape(new_current); |
11316 } | 11382 } |
11317 | 11383 |
11318 | 11384 |
11319 // Helper function to find or create the arguments object for | 11385 // Helper function to find or create the arguments object for |
11320 // Runtime_DebugEvaluate. | 11386 // Runtime_DebugEvaluate. |
(...skipping 1516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12837 } else { | 12903 } else { |
12838 // Handle last resort GC and make sure to allow future allocations | 12904 // Handle last resort GC and make sure to allow future allocations |
12839 // to grow the heap without causing GCs (if possible). | 12905 // to grow the heap without causing GCs (if possible). |
12840 isolate->counters()->gc_last_resort_from_js()->Increment(); | 12906 isolate->counters()->gc_last_resort_from_js()->Increment(); |
12841 isolate->heap()->CollectAllGarbage(false); | 12907 isolate->heap()->CollectAllGarbage(false); |
12842 } | 12908 } |
12843 } | 12909 } |
12844 | 12910 |
12845 | 12911 |
12846 } } // namespace v8::internal | 12912 } } // namespace v8::internal |
OLD | NEW |