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 4835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4846 if (instance_type < FIRST_NONSTRING_TYPE) { | 4846 if (instance_type < FIRST_NONSTRING_TYPE) { |
4847 return isolate->heap()->string_symbol(); | 4847 return isolate->heap()->string_symbol(); |
4848 } | 4848 } |
4849 | 4849 |
4850 switch (instance_type) { | 4850 switch (instance_type) { |
4851 case ODDBALL_TYPE: | 4851 case ODDBALL_TYPE: |
4852 if (heap_obj->IsTrue() || heap_obj->IsFalse()) { | 4852 if (heap_obj->IsTrue() || heap_obj->IsFalse()) { |
4853 return isolate->heap()->boolean_symbol(); | 4853 return isolate->heap()->boolean_symbol(); |
4854 } | 4854 } |
4855 if (heap_obj->IsNull()) { | 4855 if (heap_obj->IsNull()) { |
4856 return isolate->heap()->object_symbol(); | 4856 return FLAG_harmony_typeof |
| 4857 ? isolate->heap()->null_symbol() |
| 4858 : isolate->heap()->object_symbol(); |
4857 } | 4859 } |
4858 ASSERT(heap_obj->IsUndefined()); | 4860 ASSERT(heap_obj->IsUndefined()); |
4859 return isolate->heap()->undefined_symbol(); | 4861 return isolate->heap()->undefined_symbol(); |
4860 case JS_FUNCTION_TYPE: | 4862 case JS_FUNCTION_TYPE: |
4861 return isolate->heap()->function_symbol(); | 4863 return isolate->heap()->function_symbol(); |
4862 default: | 4864 default: |
4863 // For any kind of object not handled above, the spec rule for | 4865 // For any kind of object not handled above, the spec rule for |
4864 // host objects gives that it is okay to return "object" | 4866 // host objects gives that it is okay to return "object" |
4865 return isolate->heap()->object_symbol(); | 4867 return isolate->heap()->object_symbol(); |
4866 } | 4868 } |
(...skipping 3440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8307 isolate->heap()->AllocateCatchContext(function, | 8309 isolate->heap()->AllocateCatchContext(function, |
8308 isolate->context(), | 8310 isolate->context(), |
8309 name, | 8311 name, |
8310 thrown_object); | 8312 thrown_object); |
8311 if (!maybe_context->To(&context)) return maybe_context; | 8313 if (!maybe_context->To(&context)) return maybe_context; |
8312 isolate->set_context(context); | 8314 isolate->set_context(context); |
8313 return context; | 8315 return context; |
8314 } | 8316 } |
8315 | 8317 |
8316 | 8318 |
| 8319 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushBlockContext) { |
| 8320 NoHandleAllocation ha; |
| 8321 ASSERT(args.length() == 2); |
| 8322 SerializedScopeInfo* scope_info = SerializedScopeInfo::cast(args[0]); |
| 8323 JSFunction* function; |
| 8324 if (args[1]->IsSmi()) { |
| 8325 // A smi sentinel indicates a context nested inside global code rather |
| 8326 // than some function. There is a canonical empty function that can be |
| 8327 // gotten from the global context. |
| 8328 function = isolate->context()->global_context()->closure(); |
| 8329 } else { |
| 8330 function = JSFunction::cast(args[1]); |
| 8331 } |
| 8332 Context* context; |
| 8333 MaybeObject* maybe_context = |
| 8334 isolate->heap()->AllocateBlockContext(function, |
| 8335 isolate->context(), |
| 8336 scope_info); |
| 8337 if (!maybe_context->To(&context)) return maybe_context; |
| 8338 isolate->set_context(context); |
| 8339 return context; |
| 8340 } |
| 8341 |
| 8342 |
8317 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) { | 8343 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) { |
8318 HandleScope scope(isolate); | 8344 HandleScope scope(isolate); |
8319 ASSERT(args.length() == 2); | 8345 ASSERT(args.length() == 2); |
8320 | 8346 |
8321 CONVERT_ARG_CHECKED(Context, context, 0); | 8347 CONVERT_ARG_CHECKED(Context, context, 0); |
8322 CONVERT_ARG_CHECKED(String, name, 1); | 8348 CONVERT_ARG_CHECKED(String, name, 1); |
8323 | 8349 |
8324 int index; | 8350 int index; |
8325 PropertyAttributes attributes; | 8351 PropertyAttributes attributes; |
8326 ContextLookupFlags flags = FOLLOW_CHAINS; | 8352 ContextLookupFlags flags = FOLLOW_CHAINS; |
(...skipping 1320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9647 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); | 9673 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); |
9648 return object->PrepareElementsForSort(limit); | 9674 return object->PrepareElementsForSort(limit); |
9649 } | 9675 } |
9650 | 9676 |
9651 | 9677 |
9652 // Move contents of argument 0 (an array) to argument 1 (an array) | 9678 // Move contents of argument 0 (an array) to argument 1 (an array) |
9653 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) { | 9679 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) { |
9654 ASSERT(args.length() == 2); | 9680 ASSERT(args.length() == 2); |
9655 CONVERT_CHECKED(JSArray, from, args[0]); | 9681 CONVERT_CHECKED(JSArray, from, args[0]); |
9656 CONVERT_CHECKED(JSArray, to, args[1]); | 9682 CONVERT_CHECKED(JSArray, to, args[1]); |
9657 HeapObject* new_elements = from->elements(); | 9683 FixedArrayBase* new_elements = from->elements(); |
9658 MaybeObject* maybe_new_map; | 9684 MaybeObject* maybe_new_map; |
9659 if (new_elements->map() == isolate->heap()->fixed_array_map() || | 9685 if (new_elements->map() == isolate->heap()->fixed_array_map() || |
9660 new_elements->map() == isolate->heap()->fixed_cow_array_map()) { | 9686 new_elements->map() == isolate->heap()->fixed_cow_array_map()) { |
9661 maybe_new_map = to->map()->GetFastElementsMap(); | 9687 maybe_new_map = to->map()->GetFastElementsMap(); |
9662 } else if (new_elements->map() == | 9688 } else if (new_elements->map() == |
9663 isolate->heap()->fixed_double_array_map()) { | 9689 isolate->heap()->fixed_double_array_map()) { |
9664 maybe_new_map = to->map()->GetFastDoubleElementsMap(); | 9690 maybe_new_map = to->map()->GetFastDoubleElementsMap(); |
9665 } else { | 9691 } else { |
9666 maybe_new_map = to->map()->GetSlowElementsMap(); | 9692 maybe_new_map = to->map()->GetSlowElementsMap(); |
9667 } | 9693 } |
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10632 Handle<JSObject> catch_scope = | 10658 Handle<JSObject> catch_scope = |
10633 isolate->factory()->NewJSObject(isolate->object_function()); | 10659 isolate->factory()->NewJSObject(isolate->object_function()); |
10634 RETURN_IF_EMPTY_HANDLE_VALUE( | 10660 RETURN_IF_EMPTY_HANDLE_VALUE( |
10635 isolate, | 10661 isolate, |
10636 SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode), | 10662 SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode), |
10637 Handle<JSObject>()); | 10663 Handle<JSObject>()); |
10638 return catch_scope; | 10664 return catch_scope; |
10639 } | 10665 } |
10640 | 10666 |
10641 | 10667 |
| 10668 // Create a plain JSObject which materializes the block scope for the specified |
| 10669 // block context. |
| 10670 static Handle<JSObject> MaterializeBlockScope( |
| 10671 Isolate* isolate, |
| 10672 Handle<Context> context) { |
| 10673 ASSERT(context->IsBlockContext()); |
| 10674 Handle<SerializedScopeInfo> serialized_scope_info( |
| 10675 SerializedScopeInfo::cast(context->extension())); |
| 10676 ScopeInfo<> scope_info(*serialized_scope_info); |
| 10677 |
| 10678 // Allocate and initialize a JSObject with all the arguments, stack locals |
| 10679 // heap locals and extension properties of the debugged function. |
| 10680 Handle<JSObject> block_scope = |
| 10681 isolate->factory()->NewJSObject(isolate->object_function()); |
| 10682 |
| 10683 // Fill all context locals. |
| 10684 if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) { |
| 10685 if (!CopyContextLocalsToScopeObject(isolate, |
| 10686 serialized_scope_info, scope_info, |
| 10687 context, block_scope)) { |
| 10688 return Handle<JSObject>(); |
| 10689 } |
| 10690 } |
| 10691 |
| 10692 return block_scope; |
| 10693 } |
| 10694 |
| 10695 |
10642 // Iterate over the actual scopes visible from a stack frame. All scopes are | 10696 // 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 | 10697 // backed by an actual context except the local scope, which is inserted |
10644 // "artifically" in the context chain. | 10698 // "artifically" in the context chain. |
10645 class ScopeIterator { | 10699 class ScopeIterator { |
10646 public: | 10700 public: |
10647 enum ScopeType { | 10701 enum ScopeType { |
10648 ScopeTypeGlobal = 0, | 10702 ScopeTypeGlobal = 0, |
10649 ScopeTypeLocal, | 10703 ScopeTypeLocal, |
10650 ScopeTypeWith, | 10704 ScopeTypeWith, |
10651 ScopeTypeClosure, | 10705 ScopeTypeClosure, |
10652 ScopeTypeCatch | 10706 ScopeTypeCatch, |
| 10707 ScopeTypeBlock |
10653 }; | 10708 }; |
10654 | 10709 |
10655 ScopeIterator(Isolate* isolate, | 10710 ScopeIterator(Isolate* isolate, |
10656 JavaScriptFrame* frame, | 10711 JavaScriptFrame* frame, |
10657 int inlined_frame_index) | 10712 int inlined_frame_index) |
10658 : isolate_(isolate), | 10713 : isolate_(isolate), |
10659 frame_(frame), | 10714 frame_(frame), |
10660 inlined_frame_index_(inlined_frame_index), | 10715 inlined_frame_index_(inlined_frame_index), |
10661 function_(JSFunction::cast(frame->function())), | 10716 function_(JSFunction::cast(frame->function())), |
10662 context_(Context::cast(frame->context())), | 10717 context_(Context::cast(frame->context())), |
10663 local_done_(false), | 10718 local_done_(false), |
10664 at_local_(false) { | 10719 at_local_(false) { |
10665 | 10720 |
10666 // Check whether the first scope is actually a local scope. | 10721 // Check whether the first scope is actually a local scope. |
10667 if (context_->IsGlobalContext()) { | 10722 if (context_->IsGlobalContext()) { |
10668 // If there is a stack slot for .result then this local scope has been | 10723 // 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. | 10724 // 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 | 10725 // Checking for the existence of .result seems fragile, but the scope info |
10671 // saved with the code object does not otherwise have that information. | 10726 // saved with the code object does not otherwise have that information. |
10672 int index = function_->shared()->scope_info()-> | 10727 int index = function_->shared()->scope_info()-> |
10673 StackSlotIndex(isolate_->heap()->result_symbol()); | 10728 StackSlotIndex(isolate_->heap()->result_symbol()); |
10674 at_local_ = index < 0; | 10729 at_local_ = index < 0; |
10675 } else if (context_->IsFunctionContext()) { | 10730 } else if (context_->IsFunctionContext()) { |
10676 at_local_ = true; | 10731 at_local_ = true; |
10677 } else if (context_->closure() != *function_) { | 10732 } else if (context_->closure() != *function_) { |
10678 // The context_ is a with or catch block from the outer function. | 10733 // The context_ is a block or with or catch block from the outer function. |
10679 ASSERT(context_->IsWithContext() || context_->IsCatchContext()); | 10734 ASSERT(context_->IsWithContext() || |
| 10735 context_->IsCatchContext() || |
| 10736 context_->IsBlockContext()); |
10680 at_local_ = true; | 10737 at_local_ = true; |
10681 } | 10738 } |
10682 } | 10739 } |
10683 | 10740 |
10684 // More scopes? | 10741 // More scopes? |
10685 bool Done() { return context_.is_null(); } | 10742 bool Done() { return context_.is_null(); } |
10686 | 10743 |
10687 // Move to the next scope. | 10744 // Move to the next scope. |
10688 void Next() { | 10745 void Next() { |
10689 // If at a local scope mark the local scope as passed. | 10746 // 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()) { | 10781 if (context_->IsGlobalContext()) { |
10725 ASSERT(context_->global()->IsGlobalObject()); | 10782 ASSERT(context_->global()->IsGlobalObject()); |
10726 return ScopeTypeGlobal; | 10783 return ScopeTypeGlobal; |
10727 } | 10784 } |
10728 if (context_->IsFunctionContext()) { | 10785 if (context_->IsFunctionContext()) { |
10729 return ScopeTypeClosure; | 10786 return ScopeTypeClosure; |
10730 } | 10787 } |
10731 if (context_->IsCatchContext()) { | 10788 if (context_->IsCatchContext()) { |
10732 return ScopeTypeCatch; | 10789 return ScopeTypeCatch; |
10733 } | 10790 } |
| 10791 if (context_->IsBlockContext()) { |
| 10792 return ScopeTypeBlock; |
| 10793 } |
10734 ASSERT(context_->IsWithContext()); | 10794 ASSERT(context_->IsWithContext()); |
10735 return ScopeTypeWith; | 10795 return ScopeTypeWith; |
10736 } | 10796 } |
10737 | 10797 |
10738 // Return the JavaScript object with the content of the current scope. | 10798 // Return the JavaScript object with the content of the current scope. |
10739 Handle<JSObject> ScopeObject() { | 10799 Handle<JSObject> ScopeObject() { |
10740 switch (Type()) { | 10800 switch (Type()) { |
10741 case ScopeIterator::ScopeTypeGlobal: | 10801 case ScopeIterator::ScopeTypeGlobal: |
10742 return Handle<JSObject>(CurrentContext()->global()); | 10802 return Handle<JSObject>(CurrentContext()->global()); |
10743 case ScopeIterator::ScopeTypeLocal: | 10803 case ScopeIterator::ScopeTypeLocal: |
10744 // Materialize the content of the local scope into a JSObject. | 10804 // Materialize the content of the local scope into a JSObject. |
10745 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); | 10805 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); |
10746 case ScopeIterator::ScopeTypeWith: | 10806 case ScopeIterator::ScopeTypeWith: |
10747 // Return the with object. | 10807 // Return the with object. |
10748 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); | 10808 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); |
10749 case ScopeIterator::ScopeTypeCatch: | 10809 case ScopeIterator::ScopeTypeCatch: |
10750 return MaterializeCatchScope(isolate_, CurrentContext()); | 10810 return MaterializeCatchScope(isolate_, CurrentContext()); |
10751 case ScopeIterator::ScopeTypeClosure: | 10811 case ScopeIterator::ScopeTypeClosure: |
10752 // Materialize the content of the closure scope into a JSObject. | 10812 // Materialize the content of the closure scope into a JSObject. |
10753 return MaterializeClosure(isolate_, CurrentContext()); | 10813 return MaterializeClosure(isolate_, CurrentContext()); |
| 10814 case ScopeIterator::ScopeTypeBlock: |
| 10815 return MaterializeBlockScope(isolate_, CurrentContext()); |
10754 } | 10816 } |
10755 UNREACHABLE(); | 10817 UNREACHABLE(); |
10756 return Handle<JSObject>(); | 10818 return Handle<JSObject>(); |
10757 } | 10819 } |
10758 | 10820 |
10759 // Return the context for this scope. For the local context there might not | 10821 // Return the context for this scope. For the local context there might not |
10760 // be an actual context. | 10822 // be an actual context. |
10761 Handle<Context> CurrentContext() { | 10823 Handle<Context> CurrentContext() { |
10762 if (at_local_ && context_->closure() != *function_) { | 10824 if (at_local_ && context_->closure() != *function_) { |
10763 return Handle<Context>(); | 10825 return Handle<Context>(); |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11300 CopyWithContextChain(isolate, function, previous, base); | 11362 CopyWithContextChain(isolate, function, previous, base); |
11301 Handle<Context> new_current; | 11363 Handle<Context> new_current; |
11302 if (current->IsCatchContext()) { | 11364 if (current->IsCatchContext()) { |
11303 Handle<String> name(String::cast(current->extension())); | 11365 Handle<String> name(String::cast(current->extension())); |
11304 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); | 11366 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); |
11305 new_current = | 11367 new_current = |
11306 isolate->factory()->NewCatchContext(function, | 11368 isolate->factory()->NewCatchContext(function, |
11307 new_previous, | 11369 new_previous, |
11308 name, | 11370 name, |
11309 thrown_object); | 11371 thrown_object); |
| 11372 } else if (current->IsBlockContext()) { |
| 11373 Handle<SerializedScopeInfo> scope_info( |
| 11374 SerializedScopeInfo::cast(current->extension())); |
| 11375 new_current = |
| 11376 isolate->factory()->NewBlockContext(function, new_previous, scope_info); |
11310 } else { | 11377 } else { |
| 11378 ASSERT(current->IsWithContext()); |
11311 Handle<JSObject> extension(JSObject::cast(current->extension())); | 11379 Handle<JSObject> extension(JSObject::cast(current->extension())); |
11312 new_current = | 11380 new_current = |
11313 isolate->factory()->NewWithContext(function, new_previous, extension); | 11381 isolate->factory()->NewWithContext(function, new_previous, extension); |
11314 } | 11382 } |
11315 return scope.CloseAndEscape(new_current); | 11383 return scope.CloseAndEscape(new_current); |
11316 } | 11384 } |
11317 | 11385 |
11318 | 11386 |
11319 // Helper function to find or create the arguments object for | 11387 // Helper function to find or create the arguments object for |
11320 // Runtime_DebugEvaluate. | 11388 // Runtime_DebugEvaluate. |
(...skipping 1516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12837 } else { | 12905 } else { |
12838 // Handle last resort GC and make sure to allow future allocations | 12906 // Handle last resort GC and make sure to allow future allocations |
12839 // to grow the heap without causing GCs (if possible). | 12907 // to grow the heap without causing GCs (if possible). |
12840 isolate->counters()->gc_last_resort_from_js()->Increment(); | 12908 isolate->counters()->gc_last_resort_from_js()->Increment(); |
12841 isolate->heap()->CollectAllGarbage(false); | 12909 isolate->heap()->CollectAllGarbage(false); |
12842 } | 12910 } |
12843 } | 12911 } |
12844 | 12912 |
12845 | 12913 |
12846 } } // namespace v8::internal | 12914 } } // namespace v8::internal |
OLD | NEW |